在Java中初始化最终字段

在Java中初始化最终字段

问题描述:

我有一个有很多最终成员的类,它们可以使用两个构造函数之一进行实例化。构造函数共享一些代码,存储在第三个构造函数中。在Java中初始化最终字段

// 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); 
    } 

的问题是,这段代码不能编译:Variable 'two' might not have been initialized.可能有人可能来自内部MyClass的调用第一个构造函数,然后将新的对象就没有“二”中设置。

那么在这种情况下,在构造函数之间共享代码的首选方法是什么?通常我会使用一个辅助方法,但共享代码必须能够设置最终变量,这只能从构造函数完成。

+3

很难按照目前的理解你的问题,你有两个相同的* *构造函数(参数相同,相同体)。你能解决它更具代表性吗? – 2013-02-15 22:58:52

+2

在第一个构造函数中,两个未初始化。 – 2013-02-15 22:59:39

+5

@Jon Skeet - 再看看,参数类型是不同的。 – 2013-02-15 23:01:02

这个怎么样? (更新了更改的问题)

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; 
    } 
} 
+0

啊,那是我的错。我把我的例子弄乱了一点;看看我现在写的方式。然而,你给了我这样一个想法:将两个构造函数合并成一个需要SuperType的构造函数,并在调用之前调用者实际构造SuperType对象。我更喜欢在呼叫发生的地方没有SuperType,但这是我能想到的最好的。 – 2013-02-15 23:53:15

+0

可以理解。这个怎么样?它避免了允许“SuperType”的任何子类,避免重复,并总是分配给两个变量。注意,为了避免含糊不清,在'null'上进行强制转换。 https://gist.github.com/stickyd/4965120 – 2013-02-16 02:00:32

所有你需要做的就是确保“two”被初始化。在第一个构造函数,只需添加:

two = null; 

,除非是你想给它,只有第一个构造函数调用该事件的其他值。

+2

但是'two'是最终的。 – 2013-02-15 23:48:58

+0

你可以初始化一个最终变量为null。它只需要被初始化为* something *。如果你想要两个非空值,那么你必须调用其他构造函数之一。它与Sticky的答案有着相同的最终结果。 – Halogen 2013-02-16 00:06:07

+1

但问题是,如果我在第一个构造函数中将'two'设置为null,那么我无法在其他构造函数中设置它的实际值,因为它已被设置。 – 2013-02-18 04:40:56

,因为如果你曾打电话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); 
    } 
}