wood burning stoves 2.0*
The moose likes Cattle Drive and the fly likes where to declare those %&?!�$ variables Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Android Security Essentials Live Lessons this week in the Android forum!
JavaRanch » Java Forums » This Site » Cattle Drive
Bookmark "where to declare those %&?!�$ variables" Watch "where to declare those %&?!�$ variables" New topic
Author

where to declare those %&?!�$ variables

Pauline McNamara
Sheriff

Joined: Jan 19, 2001
Posts: 4012
    
    6
I'm passing on a good question I got along the way nitpicking. Hope y'all feel free to chime in.

Here it is (altered ever so slightly)...

...a question about private static final variables. You wanted me to move those method variables to class level. However, the style guide is all about declaring variables right before you use them...


So when do we go class level, and when not?
Pauline McNamara
Sheriff

Joined: Jan 19, 2001
Posts: 4012
    
    6
Oops, forgot to add that the context is that nasty old Say-4b assignment.
[ July 25, 2005: Message edited by: Pauline McNamara ]
Marilyn de Queiroz
Sheriff

Joined: Jul 22, 2000
Posts: 9044
    
  10
Looking at section 1.3 - Class Member Ordering, I see that "final attributes" are at the top of the class and methods are at the bottom.

It's always best to declare constants at the top of your class. Defining constants inside your methods is a bad practice.

I guess you're looking at section 3.3 - Initialization, where I see "Try to not declare a variable until just before it is used unless it will impact the performance of the code." The JVM deals with constants at compile time and other variables at run-time.
[ July 25, 2005: Message edited by: Marilyn de Queiroz ]

JavaBeginnersFaq
"Yesterday is history, tomorrow is a mystery, and today is a gift; that's why they call it the present." Eleanor Roosevelt
Joyce Lee
Ranch Hand

Joined: Jul 11, 2003
Posts: 1392
As mentioned earlier, it's more appropriate to declare constants at the top of a class instead of inside a method. By declaring a variable final means its value cannot be modified once it's assigned. A static variable is only created once per class during loading. A local variable of a method is created each time the method is invoked. See also VM specification: 2.5 Variables for details.

So what is the difference between the following two declarations?


In approach 1, the variable ONE is only created once when the Test class is loaded because it's declared as static. As it's final, the value cannot be changed once it's assigned.

In approach 2, a (local) variable ONE is created each time aMethod is invoked. As it's final, a value can only be assigned once to ONE inside aMethod().

As we can see, the obvious difference is the way variable ONE is created in both approaches.
[ July 30, 2005: Message edited by: Joyce Lee ]
Layne Lund
Ranch Hand

Joined: Dec 06, 2001
Posts: 3061
Originally posted by Joyce Lee:
As mentioned earlier, it's more appropriate to declare constants at the top of a class instead of inside a method. By declaring a variable final means its value cannot be modified once it's assigned. A static variable is only created once per class during loading. A local variable of a method is created each time the method is invoked. See also VM specification: 2.5 Variables for details.

So what is the difference between the following two declarations?


In approach 1, the variable ONE is only created once when the Test class is loaded because it's declared as static. As it's final, the value cannot be changed once it's assigned.

In approach 2, a (local) variable ONE is created each time aMethod is invoked. As it's final, a value can only be assigned once to ONE inside aMethod().

As we can see, the obvious difference is the way variable ONE is created in both approaches.

[ July 30, 2005: Message edited by: Joyce Lee ]


If the compiler is smart, it won't create either variable at run time. Since they are both marked final and have an initial value, the compiler can optimize away the variable and use a literal constant in the byte code. The compiler shouldn't allocate any memory for a variable in either case.

I don't know that this is the way it actually works, but it seems like an easy optimization to implement in the compiler. So this means that the only benefit we get from declaring class-level constants is for readability.

Layne


Java API Documentation
The Java Tutorial
Joyce Lee
Ranch Hand

Joined: Jul 11, 2003
Posts: 1392
[Layne]:If the compiler is smart, it won't create either variable at run time. Since they are both marked final and have an initial value, the compiler can optimize away the variable and use a literal constant in the byte code. The compiler shouldn't allocate any memory for a variable in either case.

I don't know that this is the way it actually works, but it seems like an easy optimization to implement in the compiler. So this means that the only benefit we get from declaring class-level constants is for readability.


Indeed, the JDK's compiler replaces the ONE with 1 since it's final and is initialized with a int literal. In this case, the performance may not be an issue. The question is, is this optimization a guarantee on every compiler? If so, why declaring class-level constant is more readable than at method-level? Any comment is welcome!
[ July 31, 2005: Message edited by: Joyce Lee ]
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
[Layne]: If the compiler is smart, it won't create either variable at run time.

I'm pretty sure the variable will be created as a static field of the class in question (allocated in memory), however most code that uses the value will be optimized so that it inlines the value at compile-time rather than accesses the value of the field. You can see that the field still exists as a field of the class using reflection:


[Joyce]: The question is, is this optimization a guarantee on every compiler?

For fields, yes, it's guaranteed by JLS3 13.4.9: "If a field is a constant variable (�4.12.4), then deleting the keyword final or changing its value will not break compatibility with pre-existing binaries by causing them not to run, but they will not see any new value for the usage of the field unless they are recompiled." Other classes have inlined the old value; they won't see the new value. As usual, reflection is sort of outside the JLS rules, as the passage quoted doesn't take reflection into account as a possible way to "see" the value of a field.

For a constant local variable, I don't know that there's any clear guarantee that all uses of the variable will be inlined with the value of the constant, as this doesn't really create a clear observable effect. (There's no way to recompile the variable without recompiling the method that uses it.) There are other effects that depend on whether the variable is constant or not, but I don't think they will tell us whether the value has necessarily been inlined. I suspect that yes it has been inlined, but I don't think there's a guarantee for a local variable. Not sure it really matters.

[Joyce]: If so, why declaring class-level constant is more readable than at method-level?

I'm not convinced it is. If the constant is only used in one method, I'm inclined to define it where it's used, locally. One possible reason to put it at class level is because that's where come other people may expect to find it, and following expectations is usually a good thing in collaborative development. If indeed it's a reasonably well-established expectation, and I don't think this one is. Some people might expect it to be local, and others class level.

If the constant is defined within a method, then regardless of expectations, it's going to be pretty obvious where to find it, since the only time you care about it is when you're looking at that method, and it's defined right there. (This assumes you keep your methods short enough to easily see the whole thing onscreen at one time, a principle that I think is a lot more important than where you declare a constant which is only used in one method.) And when reading the method - if you don't notice the declaration, how would you know it's a constant anyway? (If only there were some standard, well-established way of indicating a constant simply by the variable name.) Any given variable you may encounter may be local, or class/instance level. If you can't tell from the name which it is, then you may just have to check both places. Unless it's obvious because it's already right in front of your face, defined in the same context it's used.

Personally I don't think this matters much either way. Of course Marilyn may be able to give a better perspective on the reasoning here.


"I'm not back." - Bill Harding, Twister
Marilyn de Queiroz
Sheriff

Joined: Jul 22, 2000
Posts: 9044
    
  10
[Layne]: If the compiler is smart, it won't create either variable at run time.

I would rather not depend on the "smartness" of the compiler.

[Joyce]: If so, why declaring class-level constant is more readable than at method-level?

[Jim]: I'm not convinced it is. If the constant is only used in one method, I'm inclined to define it where it's used, locally. One possible reason to put it at class level is because that's where come other people may expect to find it, and following expectations is usually a good thing in collaborative development.

Indeed, this can be debatable.

If the constant is defined within a method, then regardless of expectations, it's going to be pretty obvious where to find it, since the only time you care about it is when you're looking at that method, and it's defined right there. (This assumes you keep your methods short enough to easily see the whole thing onscreen at one time, a principle that I think is a lot more important than where you declare a constant which is only used in one method.)

If the constant is only used once, I wonder if it really needs to be declared as a constant at all. If a variable is only used in one method, it should be declared as close as possible to where it is first used.


Ignoring the separate issue of whether a constant should be in all CAPS as the Sun Style Guide recommends or not as the Cattle Drive Style Guide demands , I agree with Jim that keeping methods short is important. In this particular case (Assignment 4-Say), where you are declaring an array (or two or three) which is relatively lengthy, moving the constant(s) outside the method helps keep the method shorter and more readable.
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
Oh, are we talking about an array? (Or two or three?) In that case, all the discussion of inlined constants is irrelevant, as arrays are not compile-time constants. Only primitives and Strings can be compile-time constants. All other objects are necessarily created at runtime. So a locally declared array would be instantiated each time a method is invoked. Which would be a good reason to declare it at class level instead.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: where to declare those %&?!�$ variables
 
Similar Threads
java (beginner)
Instance variables and primitive variables
static thing
Singletons ???
New Objects keeping old values