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
Related
In java, constants as known as keyword (final) with a value that will never change. I have seen some people create constants without declaring a static modifier. My question is, should constants be declared as a static? If so or if not, why?
If you assign a value to the final variable when declaring it, there's no point in it not being static, since each instance would have its own variable having the same value, which is wasteful.
However, if you need an instance variable whose value can only be set once (but different instances may have different values), that variable would have to be final but not static.
For example :
class Person
{
final int id;
public Person(int id) {
this.id = id;
}
}
You will first need to understand what constants do (i.e, what happens when you mark a field / local variable as final.)
When a primitive / String field is marked as final, it becomes a compile-time constant i.e, its value is passed as part of the bytecode itself. Thus its value is not computed / generated at runtime. This gives you a performance benefit.
The keyword static is used to say - this field is NOT unique for each instance of a class. You could have non-static final constants as well. Also, if a method local variable (primitive) is marked as final, it also becomes a constant.
So, No, static has nothing to do with constants. It is a design choice.
Constants with the final keyword will never change.. actually you cannot change the instance this field is referencing, but you can change values inside this instance.
Imagine this example:
class SomeClass {
final Car MYCAR;
...
}
With this code you will not be able to change the reference of MYCAR:
MYCAR = new Car(.....);
But you can do something like:
MYCAR.setPrice(10000);
So yes, there is a point in NOT making this field static if any instance of SomeClass needs to have their own copy of the object MYCAR but you don't want anyone to change the reference of this object.
Whatever you like. I would personally use static. You don't need to create an object when you declare it static. Also you can make a 'constants' file, where you store all constants like. public final static ...
So you basically use static final if it's a 'constant' used by all objects. If not, just make it final and pass it through the constructor.
Technically, the keyword final is enough for a constant since you can't change the value of final variables once assigned.
static should be used if the constant is not tied to a particular object instance.
For example, consider you have a Circle class, and you have a method to calculate area. You need the constant Pi for this purpose. Pi constant does not change from circle to circle. So it makes sense to declare Pi as a static final.
When you use keyword static in a class the all instances of class. i.e. All objects of a class share the same variable where as If you declare a class as final the it cannot be instantiated ( it's object cannot be created ). So if you declare a variable final then it can be assigned value only once.
Let suppose
class CalculateArea {
final static double PI = 3.1417;
/*write rest of the code to calculate area.
the value of PI will remain constant no matter
how many times its object is made
if you try to override the value of `PI` it will raise an error.
*/
}
By Oracle's definition,
Sometimes, you want to have variables that are common to all objects. This is accomplished with the static modifier. Fields that have the static modifier in their declaration are called static fields or class variables. They are associated with the class, rather than with any object. Every instance of the class shares a class variable, which is in one fixed location in memory.
By this definition, it is safe to deduce that a static variable belongs to the class and shouldn't be accessible for modification by any object of the class.Since all objects share it.
So this line from the same definition is a bit confusing:
Any object can change the value of a class variable...
So I tried this code and it prints 45 (although I get a warning saying "Static member accessed via instance reference"):
public class Main {
static int value = 8;
public static void main(String[] args) {
// write your code here
Main main = new Main();
main.value = 45;
System.out.println(value);
}
}
If this was a Student class, and I had a static variable called numberOfStudents, why should one object of that class be allowed to change the value of this class variable?
It's not really that "one object" can - it's just you're in code which has access to that variable, and unfortunately Java allows you to access static members (both variables and methods) as if they were instance members. This ends up with very misleading code, e.g.
Thread t = new Thread(...);
t.start();
t.sleep(1000);
The last line looks like it's asking the newly-started thread to sleep - but actually it'll make the current thread sleep.
This is basically a flaw in Java. The compiler will silently turn code like this into
Thread.sleep(1000);
or in your case
Main.value = 45;
(I believe that in an older version of Java, it would emit code that checked for nullity with the variable you were accessing the static member "through", but it doesn't even do that any more.)
Many IDEs will allow you to flag code like this with a warning or error. I would encourage you to turn on such a feature. If you see existing code like that, change it to use access the static member directly via the declaring class, so it's clear what's going on.
By this definition, it is safe to deduce that a static variable belongs to the class and shouldn't be accessible for modification by any object of the class.Since all objects share it.
No, static field is accessible for modifications, as long the access modifier allows it.
main.value = 45;
The compiler will read this line at compile-time as:
Main.value = 45;
Being able to create a class with static variables and methods so that those variables and methods are shared by all instances or objects created from the class can be very useful, see When to use static methods.
When sharing a static variable in a class between multiple instances or objects created from the class, the synchronized modifier may be required in order to ensure that if the static variable is being modified by objects in more than one thread, that data integrity is maintained, see What does synchronized mean? and also see How to synchronize a static variable among threads running different instances of a class in java.
The final key word, see How final keyword works is used to determine whether a variable is immutable or not. So if you want to have a class static variable that should be immutable or a constant then you can add the final modifier to the definition. However see Java final keyword for variables which explains that the underlying value for a reference may not be immutable in the sense that functional programming means. See also what is meant by immutable as well as Why final keyword is necessary for immutable class.
You can also use modifiers such as public to determine the visibility of variables and methods in a class, see What does public static void mean in Java.
By using modifiers such as final or private the programmer is able to finely tune the visibility and modifiability of variables in class and objects instantiated from the class.
Litle example how the compiler change the object field access to a class field access.
public class A {
static int foo = 25;
static public void main(String[] arg){
B b = new B();
A a = b;
System.out.println(b.foo);
System.out.println(a.foo);
}
}
class B extends A {
static int foo = 60;
}
The output is:
60
25
It also shows that can be confiusing as it have different behaviour as for object fields.
By this definition, it is safe to deduce that a static variable belongs to the class and shouldn't be accessible for modification by any object of the class.Since all objects share it.
No. By this definition, that static variable belongs to the class and is modifiable by any instance of the class. There is no implication that when some variable is shared that it should not be modifiable. Use final if you want that.
If this was a Student class, and I had a static variable called numberOfStudents, why should one object of that class be allowed to change the value of this class variable?
To increment the value in constructor and decrement it in finalizer, for example.
A static variable has a single instance for the whole class that defines it. When an instance is created, an instance of that static variable IS NOT CREATED. There is only one, and that one is freely modifiable by any function without the need for an instance. (unless it is declared final)
If we have a private final instance variable to be passed to a private method, do we redeclare it with final modifier in the function when passed as parameter ? eg:
public class GraphAlgo {
private final source;
public GraphAlgo(source) {
this.source = source
}
public void runAlgo() {
runAlgoUsingSource(source);
}
private runAlgoUsingSource(final source) { // here final is declared on a final field
//-- whatever.
}
}
Dont declare final for a parameter which is already a final.
Advantage. prevents duplicate final modifier
Disadvantage: Does not provide explicit picture, eg: if GraphAlgo is a 10000 line code then simply looking at the function 'runAlgoUsingSource' he would not have visual access to understand if 'source' was final or not.
Whats the general convention in this case ?
Here, source is already an instance variable. Why pass it to a method? For that matter, here,
private runAlgoUsingSource(final source) {
source is now another variable, scoped as a local variable, and named the same as your instance variable. (It also needs a type.) Whether this local source is final does not depend on whether this.source (the instance variable) is final.
No, Use final liberally.
One is for an instance variable:
private final SomeType source;
and the other is for a method:
private runAlgoUsingSource(final SomeType source) {
The first says that the instance variable cannot be changed (if it's a reference it cannot refer to a different object), the second says that the method argument cannot be changed.
This isn't a matter of convention; the two final declarations mean different things. Even if the value of a field flows into a parameter, the field can be final and the parameter non-final or vice versa.
It's a matter of debate, but my view is that you should only declare a parameter final if you need to -- and basically the only reason you need to declare a parameter final is if you use its value in an anonymous inner class. Fields, on the other hand, should be final unless you explicitly want to modify them.
The two final modifiers aren't related. One's making the instance member living on the heap final. The other's making a method's local variable (which just happens to share the same name) and is on the stack final.
Marking a method local variable final lets JVM optimise certain things (because it now knows the method does not modify it) and is a good practice. Marking the instance member final goes more on the lines of declaring an actual constant.
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.
Does this definition make sense ?
private static final String string = "Constant string";
I'm a beginner and I don't understand the difference between final and static...
It makes sense, yes. This is how constants are defined in Java.
final means that the variable cannot be reassigned - i.e. this is the only value it can have
static means that the same value is accessible from each instance of the class (it also means it can be accessed even without an instance of the class where it is declared)
(private here means this constant is accessible only to the current class (all of its instances and its static methods))
Yes, it makes sense - this is how constants are usually defined in Java.
final means that you cannot change the variable to a different String.
static means that there is only one copy of the reference, shared between different objects of that class. (reference)
Normal code-convention is that constants are named in uppercase with underscores between words, so I would say:
private static final String CONSTANT_STRING = "Constant string";
is more common.
Final means the value can't change (it's "const"), whereas static means it's a property of the class itself, rather than of an instance of the class. So yes, that kind of definition makes sense, and indeed is very common. Final constants like this tend to be static too, as there's little point in having them as instance properties as they can't change.
it's an old question, but i will add an information here for someone who find out this post(like me :)).
Yes it makes sense for a class member to be static and final, but it's nonsense if the variable is declared static in a method(a compile-time error launches).