My opinion may be controversial, but yes, I think that there are certainly situations where I would use this kind of style. However, "just to reduce the variable's scope" is not a valid argument, because that's what you are already doing. And doing something just to do it is not a valid reason. Also note that this explanation has no meaning if your team has already resolved whether this kind of syntax is conventional or not.
I am primarily a C# programmer, but I have heard that in Java, returning a password as char[]
is to allow you to reduce the time the password will stay in the memory. In this example, it will not help, because the garbage collector is permitted to collect the array from the moment it is not in use, so it matters not if the password leaves the scope. I am not arguing whether it is viable to clear the array after you are done with it, but in this case, if you want to do it, scoping the variable makes sense:
{
char[] password = getPassword();
try{
keyStore.load(new FileInputStream(keyStoreLocation), password);
keyManager.init(keyStore, password);
}finally{
Arrays.fill(password, '\0');
}
}
This is really similar to the try-with-resources statement, because it scopes the resource and performs a finalization on it after you are done. Again please note that I am not arguing for handling passwords in this manner, just that if you decide to do so, this style is reasonable.
The reason for this is that the variable is no longer valid. You have created it, used it, and invalidated its state to contain no meaningful information. It makes no sense to use the variable after this block, so it is reasonable to scope it.
Another example I can think of is when you have two variables that have a similar name and meaning, but you work with one and then with another, and you want to keep them separate. I have written this code in C#:
{
MethodBuilder m_ToString = tb.DefineMethod("ToString", MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.Final, typeofString, Type.EmptyTypes);
var il = m_ToString.GetILGenerator();
il.Emit(OpCodes.Ldstr, templateType.ToString()+":"+staticType.ToString());
il.Emit(OpCodes.Ret);
tb.DefineMethodOverride(m_ToString, m_Object_ToString);
}
{
PropertyBuilder p_Class = tb.DefineProperty("Class", PropertyAttributes.None, typeofType, Type.EmptyTypes);
MethodBuilder m_get_Class = tb.DefineMethod("get_Class", MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.Final, typeofType, Type.EmptyTypes);
var il = m_get_Class.GetILGenerator();
il.Emit(OpCodes.Ldtoken, staticType);
il.Emit(OpCodes.Call, m_Type_GetTypeFromHandle);
il.Emit(OpCodes.Ret);
p_Class.SetGetMethod(m_get_Class);
tb.DefineMethodOverride(m_get_Class, m_IPattern_get_Class);
}
You can argue that I can simply declare ILGenerator il;
at the top of the method, but I also don't want to reuse the variable for different objects (kinda functional approach). In this case, the blocks make it easier to separate the jobs that are performed, both syntactically and visually. It also tells that after the block, I am done with il
and nothing should access it.
An argument against this example is using methods. Maybe yes, but in this case, the code is not that long, and separating it into different methods would also need to pass along all the variables that are used in the code.