4

我收到以下代码片段的错误

错误是:在调用超类型构造函数之前无法引用 x(并指出注释 1 中的语句)

class Con{
    int x =10;

    Con(){
        this(++x); //1
        System.out.println("x :"+x);
    }

    Con(int i){
        x=i++;
        System.out.println("x :"+x);
    }
}

在主要方法中我有这个声明

    Con c1=new Con();

我不明白这个错误。有人可以解释这里实际发生的事情吗?

4

3 回答 3

5

创建类的实例时,构造函数首先调用它的超类构造函数来初始化超类字段。一旦所有的超类构造函数都运行了,那么只有当前的构造函数继续初始化它自己的字段。

现在,当您this()在构造函数中添加调用时,它不会调用超类构造函数。这是因为,构造函数中的第一条语句要么是超类构造函数的链 - using super(),要么是同一类的不同构造函数 - using this()

因此,您不能在 中传递该字段this(),因为该字段尚未初始化。但这并没有真正的意义,你为什么要尝试做这样的事情?

请记住,编译器会在类的每个构造函数中移动字段初始化代码。因此,您的构造函数实际上等效于:

Con() {
    this(++x); //1

    // This is where initialization is done. You can't access x before it.
    x = 10;
    System.out.println("x :"+x);
}

即使有super()电话也是如此。所以,下面的代码也会给你同样的错误(考虑Con用参数化构造函数扩展另一个类):

Con() {
    super(++x); //1
    System.out.println("x :"+x);
}
于 2013-08-11T12:52:23.703 回答
2
Con(){
    this(++x); //1
    System.out.println("x :"+x);
}

此刻,Con还不存在。它首先通过调用另一个构造函数来实例化。这意味着x它还不存在(它在其他构造函数实例化后立即创建)。所以你还不能引用它。

如果你真的需要引用它,你必须使用一个静态变量

private static int x = 10;
于 2013-08-11T12:52:03.960 回答
0

构造函数中的第一次调用只能是this()or super(),如果它们都不是,那么编译器会自动插入对 super 的调用,但在你的构造函数中,你使用 this() 调用了其他构造函数。基本上每当你构造一个对象时,超类首先被初始化,然后子类的成员被初始化。所以你不能引用未初始化的成员,因为它们在超类的成员和超类本身之后被初始化。

于 2013-08-11T12:56:27.453 回答