views:

332

answers:

10

I'm cleaning up Java code for someone who starts their functions by declaring all variables up top, and initializing them to null/0/whatever, as opposed to declaring them as they're needed later on.

What are the specific guidelines for this? Are there optimization reasons for one way or the other, or is one way just good practice? Are there any cases where it's acceptable to deviate from whatever the proper way of doing it is?

Thanks!

+28  A: 

Declare variables as close to the first spot that you use them as possible. It's not really anything to do with efficiency, but makes your code much more readable. The closer a variable is declared to where it is used, the less scrolling/searching you have to do when reading the code later.

Bill the Lizard
+8  A: 

If you have a kabillion variables used in various isolated places down inside the body of a function, your function is too big.

If your function is a comfortably understandable size, there's no difference between "all up front" and "just as needed".

The only not-up-front variable would be in the body of a for statement.

for( Iterator i= someObject.iterator(); i.hasNext(); )
S.Lott
I was about to write something similar. Only thing I'd add is that I sometimes deviate from declaring at the beginning of the method if I'm declaring a variable only applicable to a particular block within the method (e.g. within an else statement block).
Adamski
@Adamski: The "in an else block" vs. "in an if block" variables are very, very rare. The `if` and `else` structures must have parallel side-effects and a one-side-only local variable is a real rarity.
S.Lott
+3  A: 

I've found that declaring them as-needed results in fewer mistakes than declaring them at the beginning. I've also found that declaring them at the minimum scope possible to also prevent mistakes.

When I looked at the byte-code generated by the location of the declaration few years ago, I found they were more-or-less identical. There were ocassionally differences depending on when they were assigned. Even something like:

for(Object o : list) {
   Object temp = ...;  //was not "redeclared" every loop iteration
}

vs

Object temp;
for(Object o : list) {
   temp = ...; //nearly identical bytecoode, if not exactly identical.
}

Came out more or less identical

James Schek
+1  A: 

Its a matter of readability and personal preference rather than performance. The compiler does not care and will generate the same code anyway.

Vincent Ramdhanie
+1  A: 

I've seen people declare at the top and at the bottom of functions. I prefer the top, where I can see them quickly. It's a matter of choice and preference.

pave
Are you thinking the top and bottom of classes? You can't really declare a variable at the bottom of a function (after it's used). When I read his question I was thinking of member variables and not method variables--so maybe that's what you are thinking too...
Bill K
+6  A: 

From the Java Code Conventions, Chapter 6 on Declarations:

6.3 Placement

Put declarations only at the beginning of blocks. (A block is any code surrounded by curly braces "{" and "}".) Don't wait to declare variables until their first use; it can confuse the unwary programmer and hamper code portability within the scope.

void myMethod() {
    int int1 = 0;         // beginning of method block

    if (condition) {
        int int2 = 0;     // beginning of "if" block
        ...
    }
}

The one exception to the rule is indexes of for loops, which in Java can be declared in the for statement:

for (int i = 0; i < maxLoops; i++) { ... }

Avoid local declarations that hide declarations at higher levels. For example, do not declare the same variable name in an inner block:

int count;
...
myMethod() {
    if (condition) {
        int count = 0;     // AVOID!
        ...
    }
    ...
}
Tim
Shame on you, Sun, shame on you!
Michael Borgwardt
Tim
We need to get that fixed...
Tom Hawtin - tackline
I suspect that this text is very old, with "confuse the unwary programmer" referring to large numbers of C programmers new to Java. Nowadays this case is very rare, but the text was never revised.
Michael Borgwardt
+10  A: 

The proper way is to declare variables exactly when they are first used and minimize their scope in order to make the code easier to understand.

Declaring variables at the top of functions is a holdover from C (where it was required), and has absolutely no advantages (variable scope exists only in the source code, in the byte code all local variables exist in sequence on the stack anyway). Just don't do it, ever.

Some people may try to defend the practice by claiming that it is "neater", but any need to "organize" code within a method is usually a strong indication that the method is simply too long.

Michael Borgwardt
+3  A: 

I am doing this very same thing at the moment. All of the variables in the code that I am reworking are declared at the top of the function. I've seen as I've been looking through this that several variables are declared but NEVER used or they are declared and operations are being done with them (ie parsing a String and then setting a Calendar object with the date/time values from the string) but then the resulting Calendar object is NEVER used.

I am going through and cleaning these up by taking the declarations from the top and moving them down in the function to a spot closer to where it is used.

Jeremy Cron
Jeremy - I don't know what build tool you're using, but eclipse has an option to warn you when a local variable is never used - it's just a simple two-click process to remove those :)
MetroidFan2002
Most of the IDE tools I've seen won't catch a conceptually-not-used, such as "MyObject o = new MyObject(); o.SetFlag(true);" and then never used again. Sure, it was technically used, but may not serve any real purpose.
James Schek
@MetroidFan2002 - I'm not using a build tool. I'm in an environment that uses jsp pages that when executed generate vxml and return them to the vxml browser. The editor in this environment doesn't have a compiler so even simple syntax errors aren't caught until I deploy it to the test server. I've gotten around this by writing some in BlueJ and some in Notepad++ but I've just come to accept the fact that this is a bad development environment. Luckily the next release of this environment uses Eclipse.
Jeremy Cron
+3  A: 

Defining variable in a wider scope than needed hinders understandability quite a bit. Limited scope signals that this variable has meaning for only this small block of code and you can not think about when reading further. This is a pretty important issue because of the tiny short-term working memory that the brain has (it said that on average you can keep track of only 7 things). One less thing to keep track of is significant.

Similarly you really should try to avoid variables in the literal sense. Try to assign all things once, and declare them final so this is known to the reader. Not having to keep track whether something changes or not really cuts the cognitive load.

Ants Aasma
+1  A: 

I think it is actually objectively provable that the declare-at-the-top style is more error-prone.

If you mutate-test code in either style by moving lines around at random (to simulate a merge gone bad or someone unthinkingly cut+pasting), then the declare-at-the-top style has a greater chance of compiling while functionally wrong.

I don't think declare-at-the-top has any corresponding advantage that doesn't come down to personal preference.

So assuming you want to write reliable code, learn to prefer doing just-in-time declaration.

soru