Reputation: 1608
Lets say I have a situation like this.
private final A a;
private final B b;
private final C c;
private ClassX(){
this.c = createCSomehow();
}
public ClassX(A a){
this();
this.a = a;
this.b = null;
}
public ClassX(B b) {
this();
this.b = b;
this.a = null;
}
Why Idea is complaining about a and b property? Idea underline them and say: Variable a might not have been initialized. I am sure that I have no more constructors and that in every case a will be populated with some value.
Upvotes: 2
Views: 16302
Reputation: 23
In java all the final field must be initialize to some value. They can be assign value only once either where they are declared or in the constructor. If some final field is not initialize with declaration then it should be initialize in the all the constructor.
Upvotes: 1
Reputation: 8078
As mentioned in the other answers, after leaving a constructor your final fields must be initialized. Hence provide one constructor which initializes all fields and reuse it by the public
constructors to provide the concrete values. Like this code:
private ClassX(A a, B b) {
this.a = a;
this.b = b;
this.c = createCSomehow();
}
public ClassX(A a){
this(a, null);
}
public ClassX(B b) {
this(null, b);
}
Upvotes: 1
Reputation: 4825
As Jeremy already said in comment, there could be some code that calls the private
constructor instead of the intended public
ones.
Concerning the fix, I prefer a pattern where 1 (private?) constructor sets all variables, and other additional constructors call this "main" constructor, e.g.:
private ClassX(A a, B b){
this.a = a;
this.b = b;
this.c = createCSomehow();
}
public ClassX(A a){
this(a, null);
}
public ClassX(B b) {
this(null, b);
}
Upvotes: 1
Reputation: 394
What about the case where the constructor that takes no arguments is called, c is the only object variable that's being initialized. The object variables a and b only get initialized in the constructors that take arguments. So the fix should be as follows?
final A a;
final B b;
final C c = createCSomehow();
public ClassX() {
a = null;
b = null;
}
public ClassX(A a) {
this.a = a;
b = null;
}
public ClassX(B b) {
a = null;
this.b = b;
}
Upvotes: 0
Reputation: 111
As per the JLS specs http://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.3.1.2
A blank final instance variable must be definitely assigned (§16.9) at the end of every constructor (§8.8) of the class in which it is declared; otherwise a compile-time error occurs. This is why Idea is complaining.
Upvotes: 6
Reputation: 48837
I don't really know how to properly answer the why (JLS investigation needed), but for the how, the following should compile:
private final A a;
private final B b;
private final C c = createCSomehow();
public Main(A a){
this.a = a;
this.b = null;
}
public Main(B b) {
this.b = b;
this.a = null;
}
Upvotes: 6