在Java中初始化final字段
我有一个拥有很多最终成员的类,可以使用两个构造函数中的一个进行实例化。构造函数共享一些代码,这些代码存储在第三个构造函数中在Java中初始化final字段,java,Java,我有一个拥有很多最终成员的类,可以使用两个构造函数中的一个进行实例化。构造函数共享一些代码,这些代码存储在第三个构造函数中 // SubTypeOne and SubTypeTwo both extend SuperType public class MyClass { private final SomeType one; private final SuperType two; private MyClass(SomeType commonArg) {
// 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);
}
问题是此代码未编译:变量“two”可能尚未初始化。
有人可能从MyClass内部调用第一个构造函数,然后新对象将没有“two”字段集
那么,在这种情况下,构造函数之间共享代码的首选方式是什么?通常我会使用一个helper方法,但是共享代码必须能够设置最终变量,这只能从构造函数中完成。您需要做的就是确保初始化“2”。在第一个构造函数中,只需添加:
// 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);
}
two = null;
除非在只调用第一个构造函数的情况下,您想给它一些其他值。这个怎么样?(因问题变更而更新)
出现此错误是因为如果调用了
MyClass(SomeType oneIn)
,two
未初始化。您需要确保在每个构造函数中初始化所有最终变量。我要做的是让一个构造函数初始化所有变量,让所有其他构造函数调用它,传入null
或一些默认值(如果有一个字段没有给它们赋值)
例如:
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);
}
}
很难理解您的问题,因为目前您有两个相同的构造函数(相同的参数,相同的主体)。你能把它改得更具代表性吗?在第一个构造函数中,两个没有初始化。@Jon Skeet-再看看,参数类型是不同的。@DonRoby:谢谢,是的,我错过了。啊,那是我的错。我把我的例子搞砸了一点;看看我现在写的方式。但是,您给了我一个想法,将两个构造函数组合成一个接受超类型的构造函数,并让调用方在调用之前实际构造超类型对象。我宁愿在调用发生的地方不让超类型可见,但这是我能想到的最好的方法。可以理解。这个怎么样?它避免了允许任何
超类型的子类
,避免了重复,并始终为这两个变量赋值。注意,强制转换为null
,以避免歧义。可以将最终变量初始化为null。它只是需要初始化为某个东西。如果希望两个构造函数具有非null值,则必须调用其他构造函数之一。它的最终结果与Sticky的答案相同,但关键是如果我在第一个构造函数中将two
设置为null,那么我就不能在其他构造函数中设置它的实际值,因为它已经被设置了。