Java Variables – Does Creating Blocks to Reduce Scope Make Sense?

javascopevariables

I'm writing a program in Java where at one point I need to load a password for my keystore. Just for fun, I tried to keep my password in Java as short as possible by doing this:

//Some code
....

KeyManagerFactory keyManager = KeyManagerFactory.getInstance("SunX509");
Keystore keyStore = KeyStore.getInstance("JKS");

{
    char[] password = getPassword();
    keyStore.load(new FileInputStream(keyStoreLocation), password);
    keyManager.init(keyStore, password);
}

...
//Some more code

Now, I know in this instance that's kinda dumb. There are a bunch of other things I could've done, most of them actually better (I could've not used a variable at all).

However, I was curious if there's a case where doing this wasn't so dumb. The only other thing I can think of is if you wanted to reuse common variable names like count, or temp, but good naming conventions and short methods make it unlikely that would be useful.

Is there a case where using blocks only to reduce variable scope makes sense?

Best Answer

First, speaking to the underlying mechanics:

In C++ scope == lifetime b/c destructors are invoked on the exit from the scope. Further, an important distinction in C/C++ we can declare local objects. In the runtime for C/C++ the compiler will generally allocate a stack frame for the method that is as large as may be needed, in advance, rather than allocating more stack space on entry to each scope (that declares variables). So, the compiler is collapsing or flattening the scopes.

The C/C++ compiler may reuse stack storage space for locals that don't conflict in usage lifetime (it generally will use analysis of the actual code to determine this rather than scope, b/c that is more accurate than scope!).

I mention C/C++ b/c Java's syntax, i.e. curly braces and scoping, is at least in part derived from that family. And also because C++ came up in question comments.

By contrast, it is not possible to have local objects in Java: all objects are heap objects, and all locals/formals are either reference variables or primitive types (btw, the same is true for statics).

Further, in Java scope and lifetime are not exactly equated: being in/out of scope is a mostly a compile time concept going to accessibility and name conflicts; nothing really happens in Java on scope exit with regard to cleanup of variables. Java's garbage collection determines (the ending point of the) lifetime of objects.

Also Java's bytecode mechanism (the output of the Java compiler) tends to promote user variables declared within limited scopes to the top level of the method, because there is no scope feature at the bytecode level (this is similar to C/C++ handling of the stack). At best the compiler could reuse local variable slots, but (unlike C/C++) only if their type is the same.

(Though, to be sure the underlying JIT compiler in the runtime could reuse the same stack storage space for two differently typed (and different slotted) locals, with sufficient analysis of the bytecode.)

Speaking to the programmer advantage, I would tend to agree with others that a (private) method is a better construct even if used only once.

Still, there is nothing really wrong with using it to deconflict names.

I have done this in rare circumstances when making individual methods is a burden. For example, when writing an interpreter using a large switch statement within a loop, I might (depending on factors) introduce a separate block for each case to keep the individual cases more separate from each other, instead of making each case a different method (each of which is only invoked once).

(Note that as code in blocks, the individual cases have access to the "break;" and "continue;" statements regarding the enclosing loop, whereas as methods would require returning booleans and the caller's use of conditionals to gain access to these control flow statements.)

Related Topic