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.
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.
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".
Yes, initialize them in the constructor of the class object you are creating.
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.
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;
}
}
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);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With