Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a difference between directly assigning a final variable and assigning a final variable in the constructor?

is there a difference between these two initializations of the final variable value?

class Test {
    final int value = 7;
    Test() {}
}

and

class Test {
    final int value;
    Test() {
        value = 7;
    }
}

--

EDIT: A more complex example, involving subclasses. "0" is printed to stdout in this case, but 7 is printed if i assign the value directly.

import javax.swing.*;
import java.beans.PropertyChangeListener;

class TestBox extends JCheckBox {

    final int value;

    public TestBox() {
        value = 7;
    }

    public void addPropertyChangeListener(PropertyChangeListener l) {
        System.out.println(value);
        super.addPropertyChangeListener(l); 
    }

    public static void main(String... args) {
        JFrame frame = new JFrame();
        JPanel panel = new JPanel();
        frame.setContentPane(panel);
        panel.add(new TestBox());
        frame.pack();
        frame.setVisible(true);
    }
}
like image 471
scravy Avatar asked Dec 02 '11 09:12

scravy


People also ask

Can you set final variable in constructor?

In Java, non-static final variables can be assigned a value either in constructor or with the declaration. But, static final variables cannot be assigned value in constructor; they must be assigned a value with their declaration.

Can final variable be initialized in a constructor?

A final variable can only be initialized once, either via an initializer or an assignment statement.

Can we have final variable without assigning values at its declaration time?

Declaring final variable without initializationIf you declare a final variable later on you cannot modify or, assign values to it. Moreover, like instance variables, final variables will not be initialized with default values. Therefore, it is mandatory to initialize final variables once you declare them.

What happen if you make any variable as final variable?

Once we declare a variable with the final keyword, we can't change its value again. If we attempt to change the value of the final variable, then we will get a compilation error. Generally, we can consider a final variable as a constant, as the final variable acts like a constant whose values cannot be changed.


3 Answers

There is differece in byte-code level:

Source code:

  final int value;

  public TestBox() {
      value = 7;
  }

Produces following code from addPropertyChangeListener:

   0:   getstatic       #3; 
   3:   aload_0
   4:   getfield        #2; 
   7:   invokevirtual   #4; 

And source code:

final int value = 7;

public TestBox() {      
}

Produces the following code from addPropertyChangeListener:

   0:   getstatic       #3; 
   3:   bipush  7
   5:   invokevirtual   #4; 

So there is a small difference. But not practical.

Seems that compiler can handle a final variable as a constant if it is intialized in definition statement. Of course different compilers may do it different way.

like image 102
SKi Avatar answered Oct 21 '22 07:10

SKi


Tried with a very simple example and yes, when value is accessed in the parent's constructor it is unitialized (as it should be), unless it's final and initialized when declared. The process is that described by EJP, but with a #0 step: finals are initialized with the specified value, if any.

like image 33
Viruzzo Avatar answered Oct 21 '22 08:10

Viruzzo


A common misinterpretation of a final variable is that it can't change its value. The actual meaning of the final modifier (JLS 4.5.4) is that "a final variable may only be assigned to once".

You've run into one of the situations where it is possible to evaluate a so called "blank final" (declared, but not yet assigned) variable, so that it evaluates to the default value for the specified datatype, even if its later assigned a different value.

like image 1
jarnbjo Avatar answered Oct 21 '22 07:10

jarnbjo