2011-10-27 29 views
0
参数的构造函数(S)内初始化最终参考
import java.util.*; 

public Class C 
{ 
    final Vector v; 
    C() 
    { 
      v=new Vector(); 
    } 

    C(int i) 
    { 
      //Here, it is an error. v might not have been initialized. 
    } 

    public void someMethod() 
    { 
      System.out.println(v.isEmpty()); 
    } 

    public static void main(String[] args) 
    { 
      C c=new C(); 
      c.someMethod(); 
    } 
} 

上面的代码是一个编译时错误。我知道,但它说(在NetBeans中)变量v应该被初始化。当我在重载的构造函数中初始化它时,它修复了这个问题并打印出“true”。我的问题是为什么我应该在重载版本的构造函数中重新初始化它(我已经在默认构造函数中初始化了它),我甚至没有使用重载版本。为什么?需要在Java

+0

一种可能性是将其更改为最终Vector v = new Vector();'。那么你将不必在构造函数中编写它。 – Vlad

+0

这是太正确了,弗拉德,但它不会让v稍后被初始化,因为它是最终成员,如果需要的话。 – Bhavesh

+1

如果你通过构造函数来做同样的事情。如果你需要重新分配它,或者如果你不想初始化构建矢量,那么它不是最终的。 – Vlad

回答

4

当您创建一个新对象时,只会调用您的类的构造函数中的一个来初始化该对象。你似乎认为所有的构造函数都被调用,或者总是调用默认的(无参数)构造函数。事实并非如此。

所以,每个构造函数都需要初始化所有的成员变量final

请注意,从一个构造函数中,您可以使用this(...)明确地调用另一个构造函数。例如,作为C(int i)构造函数的第一行,可以添加一行:this();以调用C()构造函数。另一种解决方案是在该行,你声明它初始化成员变量:

public class C { 
    // v will be initialized, no matter which constructor will be used 
    final Vector v = new Vector(); 

    C() { 
    } 

    C(int i) { 
     // ... 
    } 

    // ... etc. 
} 

注意,你并不需要显式初始化非final成员变量;如果你没有初始化它们,Java将使用默认值对它们进行初始化(对于非基元类型变量,这是null)。但是,您确实需要明确初始化final成员变量。

另一个注意事项:Vector是一个遗留集合类。您应该更喜欢使用ArrayList

第三个注意:使用泛型使您的代码更安全。例如,如果您需要将字符串存储在列表中,请使用ArrayList<String>而不是原始类型ArrayList

5

因为重载的构造函数不会调用默认的构造函数。使用this()来调用它。

+0

+1 - 还有'v'被声明为final的事实。如果它不是最终的,那么它会很好(没有编译错误)。 – CoolBeans

1

重载的构造函数不调用其他的版本,除非你明确地

this(); 

这可能是你想做的事情去做。