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”。我的问题是为什么我应该在重载版本的构造函数中再次初始化它。(我已经在默认构造函数中初始化了一次)并且我甚至没有使用重载版本。为什么呢?
答案 0 :(得分:5)
因为重载的构造函数没有调用默认构造函数。
使用this()
来调用它。
答案 1 :(得分: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
。
答案 2 :(得分:1)
重载的构造函数不会调用其他版本,除非您使用
明确地执行此操作this();
这可能就是你想做的事。