Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Initializing final fields in Java

Tags:

java

I have a class with lots of final members which can be instantiated using one of two constructors. The constructors share some code, which is stored in a third constructor.

// SubTypeOne and SubTypeTwo both extend SuperType

public class MyClass {
    private final SomeType one;
    private final SuperType two;


    private MyClass(SomeType commonArg) {
        one = commonArg;
    }

    public MyClass(SomeType commonArg, int intIn) {
        this(commonArg);

        two = new SubTypeOne(intIn);
    }

    public MyClass(SomeType commonArg, String stringIn) {
        this(commonArg);

        two = new SubTypeTwo(stringIn);
    }

The problem is that this code doesn't compile: Variable 'two' might not have been initialized. Someone could possibly call the first constructor from inside MyClass, and then the new object would have no "two" field set.

So what is the preferred way to share code between constructors in this case? Normally I would use a helper method, but the shared code has to be able to set final variables, which can only be done from a constructor.

like image 755
Rag Avatar asked Feb 15 '13 22:02

Rag


People also ask

Do you have to initialize a final variable in Java?

Declaring final variable without initialization If 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 are final fields in Java?

A final field cannot have its value changed. A final field must have an initial value assigned to it, and once set, the value cannot be changed again. A final field is often also declared static . A field declared static and final is also called a "constant".

Can we initialize final class?

Yes, initialize them in the constructor of the class object you are creating.

Can final field be initialized in constructor?

Note that any final field must be initialized before the constructor completes. For static final fields, this means that we can initialize them: upon declaration as shown in the above example. in the static initializer block.


2 Answers

How about this? (Updated for changed question)

public class MyClass {

    private final SomeType one;
    private final SuperType two;

    public MyClass (SomeType commonArg, int intIn) {
        this(commonArg, new SubTypeOne(intIn));
    }

    public MyClass (SomeType commonArg, String stringIn) {
        this(commonArg, new SubTypeTwo(stringIn));
    }

    private MyClass (SomeType commonArg, SuperType twoIn) {
        one = commonArg;
        two = twoIn;
    }
}
like image 88
Richard Taylor Avatar answered Oct 23 '22 18:10

Richard Taylor


You need to make sure that in every constructor you are initializing all final variables. What I would do is have one constructor that initializes all the variables and have all the other constructor call that, passing in null or some default value if there is a field that they are not given a value for.

Example:

public class MyClass {
    private final SomeType one;
    private final SuperType two;

    //constructor that initializes all variables
    public MyClas(SomeType _one, SuperType _two) {
        one = _one;
        two = _two;
    }

    private MyClass(SomeType _one) {
        this(_one, null);
    }

    public MyClass(SomeType _one, SubTypeOne _two) {
        this(_one, _two);
    }

    public MyClass(SomeType _one, SubTypeTwo _two) {
        this(_one, _two);
    }
}
like image 24
scaevity Avatar answered Oct 23 '22 20:10

scaevity