Consider a static variable, for example:
private static int x;
If we try printing its value in the main method, it will be 0. So the variable is initialised. Now consider if the variable is final:
private static final int x;
This is not possible; why? We have to initialise it like private static final int x = 2;, or using a static initialiser like:
static {
x = 2;
}
A static variable is initialised by default; so why is there a compilation error if the variable is also final?
In principle the language could let you declare a static final field and have it take its default value, but in practice if you fail to give an explicit value for a static final field then it is almost always by mistake. So the compiler gives you an error here because
This code does something you almost certainly didn't want it to do (or, fails to do something you almost certainly did want to do), and
The default value will be something trivial like 0 or null, so if using that value is what you intended, then the inconvenience imposed on you is minimal; you just have to write static final int x = 0; instead of static final int x;.
In fact, being forced to write = 0 or = null explicitly makes your code easier to read, understand and maintain. Keep in mind that most code will be read hundreds or thousands of times more often than it is written, so you are actually saving time by being more verbose and explicit.
Paragraph from Oracle Documentation:
The final modifier indicates that the value of this field cannot change.
For example, the following variable declaration defines a constant named PI, whose value is an approximation of pi (the ratio of the circumference of a circle to its diameter):
static final double PI = 3.141592653589793;
Constants defined in this way cannot be reassigned, and it is a compile-time error if your program tries to do so. By convention, the names of constant values are spelled in uppercase letters. If the name is composed of more than one word, the words are separated by an underscore (_).
Edit:
Please, check the java language specification. The answer to your question is there.
NOTE: The static keyword on your question title can be removed because you should initialize all final variables and not only static final ones.
All final variables should be explicitly initialized or at the point of declaration or in every constructor of the class in which it is declared ( in this case it is named blank final variable ). This because a final variable value can't be changed after first assignment. So language raises warning to implicitly assignments to final variables to drive developer to explicitly assign a value ( even if it is the default one like '0' for Integers ).
Moreover in the specific case of a "static final" variable you can also assign the value in a static initializer of the class in which it is declared.
Related
I was preparing for Java OCA certification where I came across a similar question like that of the following one:
public class TestClass {
final int i;
public static void main(String[] args) {
TestClass t = new TestClass();
System.out.println(t.i);
}
}
As per Java, the instance and static variables are given default values. Surprisingly, this was error that was shown in my console:
error: variable i not initialized in the default constructor final int i;
Why wasn't i assigned a default value above?
Assigning default value to the final variable would defeat the entire purpose of making a variable final in the first place.
final would mean that you can't change the value once assigned.
If a default value is given to final variable then you would never be able to set the value of the variable to something else (even for the first time).
It's defined this way in the Java Language Specification:
Chapter 16. Definite Assignment
Each local variable (§14.4) and every blank final field (§4.12.4, §8.3.1.2) must have a definitely assigned value when any access of its value occurs.
[...]
For every access of a local variable or blank final field x, x must be definitely assigned before the access, or a compile-time error occurs.
Where the term "blank final field" refers to a final field with no value or initializer, and "definitely assigned" means that the field will be assigned to no matter what:
The idea behind definite assignment is that an assignment to the local variable or blank final field must occur on every possible execution path to the access. Similarly, the idea behind definite unassignment is that no other assignment to the blank final variable is permitted to occur on any possible execution path to an assignment.
Aside from throwing an error by specification, there's logical reasoning behind the decision. There's no point in having a default value for a blank final field. In your case, the blank final is an integer, and it would just be given 0 and you wouldn't be able to change it. What would the use of the variable be?
Also, if a final variable is not explicitly given a default value, why not initialize it in the first place? You can't reassign to it later since a default value would already be given, so why not initialize it now?
Error message is misleading since it can be initialized with default value:
class FinalTest{
final int x = printXAndInitializeIt();
private int printXAndInitializeIt(){
System.out.println("x before initialization = "+x);
return 1;
}
public static void main(String[] args) {
FinalTest ft = new FinalTest();
System.out.println("x after initialization = "+ft.x);
}
}
Output:
x before initialization = 0
x after initialization = 1
But even if there is default value final variable expects explicit initialization, since in most cases lack of initialization is caused by mistake. This error could be changed to warning, but I am guessing that Java designers though that "better safe than sorry".
It's not that final fields aren't initialized to the default value — in fact they sort of are, though you'll only observe the fact if you're doing some silly stuff — but that you're required to explicitly initialize them exactly once (either as part of the declaration, or in an initializer block, or in every single constructor).
To understand the motivation for this, consider the following code:
public class Foo {
private final int mValue;
public Foo(final boolean shouldSet) {
if (shouldSet) {
mValue = 1;
}
}
// ...
}
If the field weren't final, then the compiler would infer an implicit = 0 at the end of its declaration; but with a final field that's not always valid . . . and in the above example, the compiler can't even tell beforehand whether it will be valid or not. So the compiler sidesteps the issue by never inferring an implicit = 0, and requiring explicit initialization.
Why didn't it assign a default value in the above case ? Can anyone
explain!
if a default value were to be provided then you wouldn't be able to change the value of it. when the final keyword is used with variables it means once the variable is assigned, it cannot be re-assigned.
Wikipedia:
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. A blank final instance variable of a class must be
definitely assigned in every constructor of the class in which it is
declared; similarly, a blank final static variable must be definitely
assigned in a static initializer of the class in which it is declared;
otherwise, a compile-time error occurs in both cases. (Note: If the
variable is a reference, this means that the variable cannot be
re-bound to reference another object. But the object that it
references is still mutable, if it was originally mutable.)
further reading:
Definite Assignment
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.
*/
}
I wanted to understand what am missing in the usage of final variable. I tried googling a lot about this strange (to me at least) behavior, and would love to know what happens behind the scenes.
Java Specification says:
A variable can be declared final. A final variable may only be assigned to once. Declaring a variable > final can serve as useful documentation that its value will not change and can help avoid programming > errors.
It is a compile-time error if a final variable is assigned to unless it is definitely unassigned (§16) > immediately prior to the assignment.
A blank final is a final variable whose declaration lacks an initializer.
Now consider the following code:
public class Sample {
private final int a;
private final Object object1; // compile error that object1 is not initialized
private final Object object2 = null;
public Sample(int value) {
System.out.println(this.a);
a = value;
System.out.println(this.a);
object2 = new Object(); // Compile error that it shouldn't change
}
}
Below are my observations:
In line 2 public final int a the JVM will assign a default value of 0 to a
Which is why the first print statement in the Constructor prints value "0"
Then we are trying to modify the default value to a "value" (a=value) that is passed to the constructor
It allows to change the value, and then from the next assignment the compiler will give an error.
While in the case of Objects private final Object object1 it gives a compile time error that object1 is not initialized. Though by default JVM assigns a "null" value for instance members by default.
Once a value for the object is assigned private final Object object2=null then it works pretty much as expected.
Now can someone answer, why the compiler behaves differently with the default assignments to primitives and objects when final keyword is used?
In case if you feel if this a dumb question am sorry, but I request you to point to a source where I can get the answer.
Thanks
Sharath
In line 2 public final int a the JVM will assign a default value of 0 to a
That's what the JVM does. That's not what the compiler does - it's not an assignment within the source code. It's just the value the variable has before it's assigned any other value.
The JLS doesn't say that you can't observe the value of a final variable changing within a constructor. It says that you must assign to a final variable exactly once. That's exactly the case for a - the only assignment to it is within the constructor, so it's fine.
There's no difference between primitives and classes here - if you explicitly assign a value of 0 to a in the field declaration, you'll see the same error when you try to assign to a within the constructor.
I've found a couple of references (for example) that suggest using final as much as possible and I'm wondering how important that is. This is mainly in the the context of method parameters and local variables, not final methods or classes. For constants, it makes obvious sense.
On one hand, the compiler can make some optimizations and it makes the programmer's intent clearer. On the other hand, it adds verbosity and the optimizations may be trivial.
Is it something I should make an effort to remember?
Obsess over:
Final fields - Marking fields as final forces them to be set by end of construction, making that field reference immutable. This allows safe publication of fields and can avoid the need for synchronization on later reads. (Note that for an object reference, only the field reference is immutable - things that object reference refers to can still change and that affects the immutability.)
Final static fields - Although I use enums now for many of the cases where I used to use static final fields.
Consider but use judiciously:
Final classes - Framework/API design is the only case where I consider it.
Final methods - Basically same as final classes. If you're using template method patterns like crazy and marking stuff final, you're probably relying too much on inheritance and not enough on delegation.
Ignore unless feeling anal:
Method parameters and local variables - I RARELY do this largely because I'm lazy and I find it clutters the code. I will fully admit that marking parameters and local variables that I'm not going to modify is "righter". I wish it was the default. But it isn't and I find the code more difficult to understand with finals all over. If I'm in someone else's code, I'm not going to pull them out but if I'm writing new code I won't put them in. One exception is the case where you have to mark something final so you can access it from within an anonymous inner class.
Edit: note that one use case where final local variables are actually very useful as mentioned by #adam-gent is when value gets assigned to the var in the if/else branches.
Is it something I should make an effort to remember to do?
No, if you are using Eclipse, because you can configure a Save Action to automatically add these final modifiers for you. Then you get the benefits for less effort.
I use final all the time to make Java more expression based. See Java's conditions (if,else,switch) are not expression based which I have always hated especially if your used to functional programming (ie ML, Scala or Lisp).
Thus you should try to always (IMHO) use final variables when using conditions.
Let me give you an example:
final String name;
switch(pluginType) {
case CANDIDATE_EXPORT:
name = "Candidate Stuff";
break;
case JOB_POSTING_IMPORT:
name = "Blah";
break;
default:
throw new IllegalStateException();
}
Now If add another case statement and do not set name the compiler will fail. The compiler will also fail if you do not break on every case (that you set the variable). This allows you to make Java very similar to Lisp's let expressions and makes it so your code is not massively indented (because of lexical scoping variables).
And as #Recurse noted (but apparently -1 me) you can do the preceding with out making String name final to get the compiler error (which I never said you couldn't) but you could easily make the compiler error go away setting name after the switch statement which throws away the expression semantics or worse forgetting to break which you cannot cause an error (despite what #Recurse says) without using final:
String name;
switch(pluginType) {
case CANDIDATE_EXPORT:
name = "Candidate Stuff";
//break; whoops forgot break..
//this will cause a compile error for final ;P #Recurse
case JOB_POSTING_IMPORT:
name = "Blah";
break;
}
// code, code, code
// Below is not possible with final
name = "Whoops bug";
Because of the bug setting name (besides forgetting to break which also another bug) I can now accidentally do this:
String name;
switch(pluginType) {
case CANDIDATE_EXPORT:
name = "Candidate Stuff";
break;
//should have handled all the cases for pluginType
}
// code, code, code
// Below is not possible with final
name = "Whoops bug";
The final variable forces a single evaluation of what name should be. Similar to how a function that has a return value must always return a value (ignoring exceptions) the name switch block will have to resolve name and thus bound to that switch block which makes refactoring chunks of code easier (ie Eclipe refactor: extract method).
The above in OCaml:
type plugin = CandidateExport | JobPostingImport
let p = CandidateExport
let name = match p with
| CandidateExport -> "Candidate Stuff"
| JobPostingImport -> "Blah" ;;
The match ... with ... evaluates like a function ie expression. Notice how it looks like our switch statement.
Here is an example in Scheme (Racket or Chicken):
(define name
(match b
['CandidateExport "Candidate Stuff"]
['JobPostingImport "Blah"]))
The development-time benefits of "final" are at least as significant as the run-time benefits. It tells future editors of the code something about your intentions.
Marking a class "final" indicates that you've not made an effort during design or implementation of the class to handle extension gracefully. If the readers can make changes to the class, and want to remove the "final" modifier, they can do so at their own risk. It's up to them to make sure the class will handle extension well.
Marking a variable "final" (and assigning it in the constructor) is useful with dependency injection. It indicates the "collaborator" nature of the variable.
Marking a method "final" is useful in abstract classes. It clearly delineates where the extension points are.
Well, this all depends on your style... if you LIKE seeing the final when you won't be modifying the variable, then use it. If you DON'T LIKE seeing it... then leave it out.
I personally like as little verbosity as possible, so I tend to avoid using extra keywords that aren't really necessary.
I prefer dynamic languages though, so it's probably no surprise I like to avoid verbosity.
So, I would say just pick the direction you are leaning towards and just go with it (whatever the case, try to be consistent).
As a side note, I have worked on projects that both use and don't use such a pattern, and I have seen no difference in the amount of bugs or errors... I don't think it is a pattern that will hugely improve your bug count or anything, but again it is style, and if you like expressing the intent that you won't modify it, then go ahead and use it.
I've found marking method parameters and locals as final is useful as a refactoring aid when the method in question is an incomprehensible mess several pages long. Sprinkle final liberally, see what "cannot assign to final variable" errors the compiler (or your IDE) throws up, and you just might discover why the variable called "data" ends up null even though several (out of date) comments swear that can't happen.
Then you can fix some of the errors by replacing the reused variables with new variables declared closer to the point of use. Then you find you can wrap whole parts of the method in scoping braces, and suddenly you're one IDE keypress away from "Extract Method" and your monster just got more comprehensible.
If your method is not already an unmaintainable wreck, I guess there might be value in making stuff final to discourage people from turning it into said wreck; but if it's a short method (see: not unmaintainable) then you risk adding a lot of verbosity. In particular, Java function signatures are hard enough to fit into 80 characters as it is without adding six more per argument!
It is useful in parameters to avoid change the parameter value by accident and introduce a subtle bug. I use to ignore this recommendation but after spending some 4 hrs. in a horrible method ( with hundreds of lines of code and multiple fors, nested ifs and all sort of bad practices ) I would recommend you to do it.
public int processSomethingCritical( final int x, final int y ){
// hundreds of lines here
// for loop here...
int x2 = 0;
x++; // bug aarrgg...
// hundreds of lines there
// if( x == 0 ) { ...
}
Of course in a perfect world this wouldn't happen, but.. well.. sometimes you have to support others code. :(
If you are writing a application that someone will have to read the code after, say, 1 year, then yes, use final on variable that should not be modified all the time. By doing this, your code will be more "self-documenting" and you also reduce the chance for other developers to do silly things like using a local constant as a local temporary variable.
If you're writing some throwaway code, then, nah, don't bother to identify all the constant and make them final.
I will use final as much as I can. Doing so will flag if you unintentionally change the field. I also set Method parameters to final. Doing so I have caught several bug from code I have taken over when they try to 'set' a parameter forgetting Java passes by value.
It's not clear from the question whether this is obvious, but making a method parameter final affects only the body of the method. It does NOT convey any interesting information about the method's intentions to the invoker. The object being passed in can still be mutated within the method (finals are not consts), and the scope of the variable is within the method.
To answer your precise question, I wouldn't bother making an instance or local variable (including method parameters) final unless the code required it (e.g. the variable is referenced from an inner class), or to clarify some really complicated logic.
For instance variables, I would make them final if they are logically constants.
There are many uses for the variable final. Here are just a few
Final Constants
public static class CircleToolsBetter {
public final static double PI = 3.141;
public double getCircleArea(final double radius) {
return (Math.pow(radius, 2) * PI);
}
}
This can be used then for other parts of your codes, or accessed by other classes, that way if you would ever change the value you wouldn't have to change them one by one.
Final Variables
public static String someMethod(final String environmentKey) {
final String key = "env." + environmentKey;
System.out.println("Key is: " + key);
return (System.getProperty(key));
}
}
In this class, you build a scoped final variable that adds a prefix to the parameter environmentKey. In this case, the final variable is final only within the execution scope, which is different at each execution of the method. Each time the method is entered, the final is reconstructed. As soon as it is constructed, it cannot be changed during the scope of the method execution. This allows you to fix a variable in a method for the duration of the method. see below:
public class FinalVariables {
public final static void main(final String[] args) {
System.out.println("Note how the key variable is changed.");
someMethod("JAVA_HOME");
someMethod("ANT_HOME");
}
}
Final Constants
public double equation2Better(final double inputValue) {
final double K = 1.414;
final double X = 45.0;
double result = (((Math.pow(inputValue, 3.0d) * K) + X) * M);
double powInputValue = 0;
if (result > 360) {
powInputValue = X * Math.sin(result);
} else {
inputValue = K * Math.sin(result); // <= Compiler error
}
These are especially useful when you have really long lines of codes, and it will generate compiler error so you don't run in to logic/business error when someone accidentally changes variables that shouldn't be changed.
Final Collections
Different case when we are talking about Collections, you need to set them as an unmodifiable.
public final static Set VALID_COLORS;
static {
Set temp = new HashSet( );
temp.add(Color.red);
temp.add(Color.orange);
temp.add(Color.yellow);
temp.add(Color.green);
temp.add(Color.blue);
temp.add(Color.decode("#4B0082")); // indigo
temp.add(Color.decode("#8A2BE2")); // violet
VALID_COLORS = Collections.unmodifiableSet(temp);
}
otherwise, if you don't set it as unmodifiable:
Set colors = Rainbow.VALID_COLORS;
colors.add(Color.black); // <= logic error but allowed by compiler
Final Classes and Final Methods cannot be extended or overwritten respectively.
EDIT:TO ADDRESS THE FINAL CLASS PROBLEM REGARDING ENCAPSULATION:
There are two ways to make a class final. The first is to use the keyword final in the class declaration:
public final class SomeClass {
// . . . Class contents
}
The second way to make a class final is to declare all of its constructors as private:
public class SomeClass {
public final static SOME_INSTANCE = new SomeClass(5);
private SomeClass(final int value) {
}
Marking it final saves you the trouble if finding out that it is actual a final, to demonstrate look at this Test class. looks public at first glance.
public class Test{
private Test(Class beanClass, Class stopClass, int flags)
throws Exception{
// . . . snip . . .
}
}
Unfortunately, since the only constructor of the class is private, it is impossible to extend this class. In the case of the Test class, there is no reason that the class should be final. The Test class is a good example of how implicit final classes can cause problems.
So you should mark it final when you implicitly make a class final by making it's constructor private.
Somewhat of a trade-off as you mention, but I prefer explicit use of something over implicit use. This will help remove some ambiguity for future maintainers of code - even if it is just you.
If you have inner (anonymous) classes, and the method needs to access variable of the containing method, you need to have that variable as final.
Other than that, what you've said is right.
Use final keyword for a variable if you are making that variable as immutable
By declaring the variable as final, it aids developers to rule out possible modification issues of variables in highly multi-threaded environment.
With java 8 release, we have one more concept called "effectively final variable". A non-final variable can heave as final variable.
local variables referenced from a lambda expression must be final or effectively final
A variable is considered effective final if it is not modified after initialization in the local block. This means you can now use the local variable without final keyword inside an anonymous class or lambda expression, provided they must be effectively final.
Till Java 7, you cannot use a non-final local variable inside an anonymous class, but from Java 8 you can
Have a look at this article
First of all, the final keyword is used to make a variable constant. Constant means it does not change. For example:
final int CM_PER_INCH = 2.54;
You would declare the variable final because a centimeter per inch does not change.
If you try to override a final value, the variable is what it was declared first. For example:
final String helloworld = "Hello World";
helloworld = "A String"; //helloworld still equals "Hello World"
There is a compile error that is something like:
local variable is accessed from inner class, must be declared final
If your variable cannot be declared final or if you don't want to declare it final try this:
final String[] helloworld = new String[1];
helloworld[0] = "Hello World!";
System.out.println(helloworld[0]);
helloworld[0] = "A String";
System.out.println(helloworld[0]);
This will print:
Hello World!
A String
In my current project I noticed that all class fields and variable inside methods are declared with final modifier whenever it's possible.
Just like here:
private final XMLStreamWriter _xmlStreamWriter;
private final Marshaller _marshaller;
private final OutputStream _documentStream;
private final OutputStream _stylesStream;
private final XMLStreamWriter _stylesStreamWriter;
private final StyleMerger _styleMerger;
public DocumentWriter(PhysicalPackage physicalPackage) throws IOException {
final Package pkg = new Package(physicalPackage);
final Part wordDocumentPart = pkg.createPart(
"/word/document.xml",
"application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml",
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument");
// styles.xml
final Pair<Part, String> wordStylesPart = wordDocumentPart.createRelatedPart(...);
...
}
Are there any reasons to do so?
p.s. As I know project is not supposed to be multithreaded (at least I've heard nothing about it).
When you write final you are signalling both to the compiler and the human reader that this variable is set once and then not changed.
The compiler uses it to check that you don't accidentally reassign a variable. If you do this it will give a compile error.
The human reader can use it to understand the intention of the code more quickly.
Missing it out typically won't cause your code to fail, but if you want a field to not change it is a good idea to say that explicitly. Note also that sometimes the final is mandatory, for example when using local classes:
In addition to accessing fields defined by the containing class, local classes can access any local variables, method parameters, or exception parameters that are in the scope of the local method definition and declared final.
On the other hand, there might be times when you do want to be able to reassign to a variable. Obviously in this case you should not declare it as final.
In programming it is best to get a compiler error than a logic error. Compiler errors are found in seconds and are corrected very fast.
final keyword can help to convert logic errors into compiler errors without too much effort.
For example:
public int test(int num){
num = 10;
x = num*2
return x;
}
In the example above we could accidentally assign a new value to num variable so the return value will be wrong. With final keyword we prevent this kind of errors.
public int test(final int num){
num = 10; //compiler error
x = num*2
return x;
}
Immutable classes are inherently thread safe in which you can share safely across threads. If you declared all fields of a class final (and the class itself is final) also assuming each field itself is immutable, that object would be safe to share across threads.
Theoretically JVM can optimize those better, but I don't know if it really does. final is used to indicate that you can assign a value to the variable only once.
And practically the object is in 2 or even more classloaders like app server environment and therefore will get assigned more than once even final. Or load a declared final from a properties file later changed, happened here removing declared final to normal variables got more pragmatic.