In Java when a final field is assigned a constant value compile-time, it usually makes sense declaring it static. It saves overhead according to the relevant PMD rule.
Does it make any sense or difference doing it in GWT regarding the generated Javascript code?
If the variable is assigned when it is declared final, then yes, static makes a certain amount of sense, but there are cases where it should not be static:
public MyClassWithFinal {
private final String finalVar;
public MyClassWithFinal(String name) {
this.finalVar = name;
}
}
Another case: If the instance var is not a string or number constant, but requires running a constructor, that constructor may have side effects each time it is invoked, so running it only once is different than running it multiple times.
That said, GWT will inline/intern constant string values, so if you have multiple String fields all assigned to the same value, GWT will probably detect that and promote them all to static.
public final String constant = "Some Constant that really ought to be static";
GWT will notice that this is never assigned except when declared, and may even remove the field itself.
The best rule is to start with the best (i.e. most readable, most maintainable, most efficient) Java code, and to only break from that in cases where GWT requires something specific. This is not one of those cases: the compiler should perform the same basic optimizations no matter how you write this.
A field marked as final doesn't mean that it is immutable, only that its reference won't point to any other memory chunk. Therefore, it can only make sense to make a field static if it is really immutable, or if it is a primitive.
For instance, it's common to declare lists as final if you want to make sure that they will never point to a different list object, but the list itself can still be filled with data, cleared, filled again, etc. And of course, each object declaring such list does not mandatory want to share it among every instances.
private final List<...> list = new ArrayList<...>();
Final keyword is there to prevent you from doing mistakes, like setting to null a reference that should never change.
Related
Is there any performance benefit by using a private final static String in java vs using a local string variable that has to get "initialized" every time the method is accessed?
I do think that using private static final strings is a good practice for constants that get reused in different parts of a class, however if a string were to be used only in one method, in one location, for a very specific reason that no other method is concerned about, I actually prefer to keep the class' internal interface clean with less private members, and just use a local variable.
Given that java has String interning, and actually keeps a pool with a single copy of each string that gets declared using quotes (String s = "some string"), would there actually be a performance hit from having to declare / initialize / assign the variable each time the method is accessed vs using a static string?
To make it a bit more clear, would there be any difference between using SS or LS?
class c {
private final static String SS = "myString";
private void method(){
//do something with SS
}
private void OtherMethod(){
String LS = "myOtherString"
//do same thing with LS
}
}
Using a named constant is likely to be better for maintainability. However constants known at compile time can be used as inline in which case there is unlikely to be any difference.
Note: if you are using a String literal, this will be created just once, no matter where in the JVM it is used.
In this case the only difference is using a local variable on the stack which is unlikely to be any more expensive than a constant which have been used as inline.
would there actually be a performance hit from having to declare the variable each time the method is accessed
As Java uses a static compiler, a variable is only declared once (or once for each stage of compilation), when loading the class/method, regardless of how many times the methods is called. The variable might be initialized each time however.
The truth is, at the end, there is no difference. A constant string in a local variable will still end up in the constant pool and optimized. So generally speaking, local variables are faster because they are easier to access, but in the case of constant strings it does not make a difference. So choose whatever is more readable and intuitive in your case.
I guess creating constants comes from old time when creating statics helped in maintaining only one string as part of the class in the jvm, rather than the object which gets created and garbage collected every time the object is created and destroyed. But with spring default scope as singleton rather than prototype, I guess it makes no difference. So, yeah, it depends how the class will be used, is the answer.
Unchangeable, constant values should be stored in constants rather than variables for both safer and cleaner code.
The latter doesn't apply to all cases of unchangeable values though: There's the following method that is only called once, on initialising the app that uses the same value of a String twice. The String is only referenced and used inside the method.
My question is: What's the best way of variable/constant definition? Being a simple String in a large application, performance and memory can be neglected, it's more about readability and maintenance.
Is it as variable inside the method:
protected void init() {
final String thestring = "thevalue";
methodA(thestring);
methodB(thestring);
}
or is it as constant on class level (although only used in the method):
private static final String THESTRING = "thevalue";
protected void init() {
methodA(THESTRING);
methodB(THESTRING);
}
or a third, better solution? Please also take into consideration that there can be more, similar methods in the same class.
For me the best solution is to use variable inside the method - because it's internal variable. So other methods shouldn't see it. Consider the encapsulation and clean code, when you try to move this variable on class level you will get a long list of class variables.
Another thing is memory. After method is executed the variables are destroyed. When you define it as a static it will be in your memory all the time.
I can think of three places to put your variable (all final ofc), each has it advantages and disadvantages.
Local variable.
Private static field inside your class.
Public static field inside some Properties class.
1 - Advantages: variable can only be seen inside your method - high code safety. Disadvatages: variable is buried inside a method, can be difficult to find and change.
(I'll skip 2 because it is just compromise between 1 and 3)
3 - Advantages: your field is among other configurable fields, that makes it easy to change your setting. Disadvantages: field is public and everyone can see it (but String is immutable so no one will be able to change it).
Summary: depends on how much you expect you will need to change your variable (e.g. balancing, color changing, ...). If you are sure that this string value is the right one, i wouldn't fear to put that into local variable.
Typically constants are not instance specific. It is thus a better practice to store constants as static variables rather than as member variables. The advantages are:
There is only one allocation of the variable instead of one allocation per object.
You don't need to create an instance variable to access a constant, e.g. PI is declared to be static in the java Math class.
Strategy for defining immutable class says that
all the fields should be final.
For ex:
private String name;
Why does it have to be final?
Since I am not giving setter methods for it? It can't be changed.
Thanks.
If you read
private final String name;
you know the field is immutable.
If you read
private String name;
you have to read the entire class to check it is not changed anywhere. This is means much more work for you.
You may remember now, having just written the class that you didn't add a setter, but after writing many more classes you read your own class six month later, you won't remember reliably.
Even if it is not changed now, someone (possibly yourself) could change it later by adding code. However, you might have made the assumption the value won't change.
In short, only make it non-final when you mean the value to change, and make it final when you didn't expect it to change. Don't leave it as a may be/may be not.
Now imagine you are used to being clear about which fields can be changed and which cannot. This saves you a lot of work when reading some else's code. But you discover that you are reading code which is not clear and non-final doesn't mean it was changed, it now means you have to check things, you wouldn't normally have to check which is one more headache in trying to understand some code you really don't need.
A simple example of how much harder it is to read code to determine if a field is effectively final.
public class A {
static class B {
private int x;
}
// some code
This all looks fine up to this point, no setters or even methods in B. So B.x is immutable right?
static class C {
public void update(B b, int x) {
b.x = x; // this really compiles
}
}
}
Oops no, you have to read the whole class file.
It is far better for you to make every field you can final (which should have been the default IMHO) when you write the code, rather than leaving it for someone to figure out later.
The main reason (IMHO) is that when field is final is guaranteed to be visible in other threads immediately after constructor is finished.
Keeping the field final emphasizes the fact that it cannot be changed anywhere else.
Self documenting code the the field should not be changed
Compiler will help you by giving error if you change the field somewhere else
So final helps in many ways for making object Immutable.
It's good practice to make immutable fields final, even on otherwise mutable objects.
Note that private fields of one object in fact CAN be accessed by other instances of the same class.
An object (class or instance) is immutable, if its internal state cannot be changed (reflection doesn't count).
Making a field final guarantees only that the value (if it's a primitive) or reference (for non-primitives) cannot be changed.
For non-primitives, this doesn't automatically mean that the referenced value is also immutable. Which means that if your final field references, for example, a list, one cannot exchange the list, but add/remove values from it, thus changing the state of the object.
For an object to be immutable:
The internal state must be determined upon construction and can never change
This means all fields that define the state must be final (you may have other helper fields which don't belong to the state, that's ok but rare).
This also means that all refernced objects must be immutable. Some objects such as String are already immutable, others such as collections can be wrapped to make them immutable (Collections.immutableList|Set|Collection|...)
Making primitive types final ensures immutability. However making non primitive objects final sometimes makes no sense since final object states can be mutated.As Greg points out this depends on the type of Object in question
As the example you showed, all properties are primitive hence final keword make sense.
One benifit of declaring a field final is that it allows compiler to detect attempts to change the field during refactoring. A class can be immutable even if its fields are not final.
JVM guarantees that final fields of a class will be initialized before any thread gets hold of the object. Without this guarantee, a reference to an object may be published, i.e. become visible, to another thread before all the fields of this object are initialized, due to reorderings or other optimizations. This could cause racy access to these fields.
This is why, when creating an immutable object, you should always make all its fields final, even if they are not accessible via getter methods.
I've got two classes below. Both have one variable 'reply' with a getter. There is no setter method for this variable. Only difference is in ClassOne, the variable is static final.
So whats the difference and which one is preferred?
public class ClassOne {
private static final String reply = "Success";
..
public String getReply() {
return reply;
}
// no setter
}
and Class 2
public class ClassTwo {
private String reply = "Success";
..
public String getReply() {
return reply;
}
// no setter
}
UPDATE 1:
What I want to know is that when there is no setter for a variable, should the variable be declared as static final for optimization? or does it not matter?
should the variable be declared as static final for optimization?
final certainly, not only for optimization but for clarity and because it can make your object immutable, which is always a good thing to have.
static completely changes the nature of the field and has nothing to do with the existence of setters: do you want only one instance of that field, or do you need one per instance of your class?
Non static example: a Person has a name, which is a constant (for a given person = per instance), so you can use a non static final field, which you only set once when creating a new Person:
private final String name;
Static example: Whenever you don't have a name for a Person, you want to use a default value - that is a global constant which is shared among all persons that don't have a name and you can use a static final field:
private static final String NO_NAME = "John Doe";
When you set the variable as final, you are telling everybody (the compiler, the runtime) that it cannot be changed. This can help a lot with optimizations like inlining all of the occurrences of the variable with its value.
When you have a constant string which can not be changed, you should make it a static final string.
Static means that less memory is needed for instance of the class, because the instances don't need individual copies.
Final allows some optimizations and thus makes your program faster.
There are few things good to know:
final variables can be checked by compiler that they are not accidentally changed.
references to non-static variables are contained in instance so there is small needless memory consumption in addition
static variables are shared across all instances of the same class, so you can be sure that all instances work with the same value
final static variables, especially the Strings are linked in compilation time so they need not to be dereferenced at runtime from the field. Due to that it cannot be changed even by the reflection, because such field is not used at runtime.
Setting the reference to final ensures you can't change the reference. Note however that if the object referred to is mutable then you could still change that (not in this instance, since Strings are immutable).
I normally make fields final and initialise them in the constructor. By favouring immutability my classes are easier to debug and are more likely to be safe in threaded environments. It's easier to remove the immutability constraint than add it.
I also do this for method arguments. Rarely (ever) do I want to change a method argument, and making them final will catch inadvertent assignments.
I try not to use static except for final constants. Unless it's something like a logger, I don't really want one instance per class, and (of course) this doesn't work in the case of multiple classloaders. It's also getting close to the singleton anti-pattern, and this impacts on easy testing and (potentially) threading.
The fact that you make the variable static means that a single instance of that variable will be shared among all the instances of ClassOne, as the variable is bound to the class itself, not to its instances. Apart from any JVM optimisations, you'll have a single instance of reply for every instance of ClassTwo.
First one is Constant you need to know value of it at compile time.
private static final String reply = "Success";
second is just simple member variable. So any case first one is preferred since second one will create value for each object.
Assuming that you intended **private final String reply** in second case
A final variable can only be initialized once, either via an initializer or an assignment statement. It does not need to be initialized at the point of declaration: this is called a "blank final" variable.
In second case you can also declare and initialize it in constructor
private final String reply;
You can read more about it here
I am new to java and could not get whether enumerations rendered final variables obsolete?
Enumerations and final variables unrelated. Prior to enums people had to resort to constants, but they are not equivalent.
Absolutely not. Final variables in Java ate for more than just constants.
Final can be applied to method parameters to provide a compile-time guarantee against reassignment.
Final can be applied to local variables to provide a compile-time guarantee against reassignment. This also is REQUIRED for instantiating anonymous inner classes that reference local variables (also known as closures).
Final can be applied to instance variables to guarantee reference immutability of those fields. If the field type is immutable or suitable defensive measures are taken, this can be used to ensure your object's immutability, making it trivially thread safe.
Final can be applied to methods to prevent subclasses from overriding them.
Final can be applied to classes to prevent extension of the class at all.
As you can see, there are still PLENTY of uses for the final keyword.
I assume in this question you are asking about integer constants rather than of any other type? If not, remember that enums can only be enums (ints) and can not be of a particular type.
Otherwise... again, it would not make them obsolete. Enums are useful where there are only a (small-ish) finite number of possibilities that will never change. Not so useful where these can be an infinite number of things (or a large number) or are not all fully defined but some can be.
It really depends on the usage.
If you mean public static final int variables used as named constants, then yes, enumerations are intended to be used in their stead.
However, final variables are still useful in a few regions -- notably, the use of closures requires them, e.g.
final int foo = 3; // must be marked final
t = new Thread(new Runnable() {
public static void run() {
System.out.println(foo + 1);
}
});
t.start();
In addition, PSF variables are still useful as configuration constants.
Well there are different applications for both. Enumerations are better for stuff like state machines or places where values are not relevant. I have a set of final variables that function as both values and state indicators in one of my programs. Final variables still have significant applications because they allow the simple modification of literal values throughout an entire program.
/nutshell