I recently ran across a class that had the following field declared:
private final int period = 1000;
In this particular case, the author had intended for it to also be static and since the value couldn't be altered at any point, there was no real functional reason not to declare it static, but it got me wondering how Java treats final vs. final static primitives.
In particular:
1) How are final static primitives stored? Are they simply compiled directly into the expressions in which they're used?
2) If they are actually allocated storage, does each instance of the containing class then have to maintain a reference to that location? (in which case, for primitives of less than 4 bytes, each instance of the class would actually be larger than if it simply included the primitive directly as it would in the non-static case)
3) Are compilers now smart enough to determine that in cases such as the one above, the variable is 'effectively static' since it would be impossible to have different instances contain different values and therefore optimize it similarly to a final static one?
The static keyword means the value is the same for every instance of the class. The final keyword means once the variable is assigned a value it can never be changed. The combination of static final in Java is how to create a constant value.
A static method has two main purposes: For utility or helper methods that don't require any object state. Since there is no need to access instance variables, having static methods eliminates the need for the caller to instantiate the object just to call the method.
Yes, static data will in a sense save memory since there's only a single copy of it. Of course, whether or not data should be static is more a function of the meaning or use of the data, not memory savings.
Non-static fields are incarnated when the class is instantiated: A field that is not declared static (sometimes called a non- static field) is called an instance variable.
1) How are final static primitives stored? Are they simply compiled directly into the expressions in which they're used?
Not compiled directly into the expressions. They are compiled into the .class file and referenced by the opcode ldc
.
2) If they are actually allocated storage, does each instance of the containing class then have to maintain a reference to that location? (in which case, for primitives of less than 4 bytes, each instance of the class would actually be larger than if it simply included the primitive directly as it would in the non-static case)
No, the "reference" is baked into the bytecode, so nothing needs to be stored on a per-instance basis.
3) Are compilers now smart enough to determine that in cases such as the one above, the variable is 'effectively static' since it would be impossible to have different instances contain different values and therefore optimize it similarly to a final static one?
Not sure, but I doubt it's optimized at the compiler level. The JIT would probably come into play. However, I'm not at all sure what sort of "performance differences" you are expecting. No matter what the case, the performance impact will be negligible. (static/non-static/final/non-final)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With