在Java中使用另一个构造函数

时间:2015-10-15 17:41:35

标签: java constructor

考虑:

    int a = 0;
    int b = 3;

    //Constructor 1
    public ClassName (int a) {
        this(a, b); //Error
        //new ClassName(a, b) //No error
    }

    //Constructor 2
    public ClassName (int a, int b) {
        this.a = a;
        this.b = b;
    }

第一个问题:

我收到错误消息“b应该是静态的”。为什么我不能以这种方式使用b的默认值(3)?

第二个问题:

在第一个构造函数中,如果我使用注释部分,我不会收到错误。这是否可以接受?

3 个答案:

答案 0 :(得分:12)

the JLS, Section 8.8.7.1禁止在显式构造函数调用中使用实例变量。

  

构造函数体中的显式构造函数调用语句可能不引用此类或任何超类中声明的任何实例变量或实例方法或内部类,或者在任何表达式中使用thissuper;否则,发生编译时错误。

     

禁止使用当前实例解释了为什么显式构造函数调用语句被认为是在静态上下文中发生的(第8.1.3节)。

您引用了实例变量b。编译器没有在a上引发此错误,因为它是一个局部变量,它会影响实例变量a

“静态上下文”可能是您的IDE建议使b静态的原因,因此可以引用它。这说得通;对象的ClassName部分尚未构建。将b的用法替换为其他内容,例如static常量或文字int值。

要回答您的其他问题,键入new ClassName(a, b)不是错误,因为此时已构建此实例,并且您正在创建一个单独的,不相关的ClassName对象。

答案 1 :(得分:6)

  

第一个问题:我收到错误说" b应该是静态"。为什么我不能以这种方式使用b的默认值(3)?

b提供其他构造函数的默认值的正确方法是this(a, 3);。在 this(...)之后之前,您无法引用实例变量。这只是该语言规则之一。

  

第二个问题:在第一个构造函数中,如果我使用注释部分,我不会收到错误。这是否可以接受?

new ClassName(a, b);做了不同的事情。它创建了一个单独的类实例。以我的拙见,这可能不是最好的事情。人们期望new创建一个类的实例,而在构造函数中使用new ClassName创建两个。

答案 2 :(得分:0)

在类中使用变量时,重要的是要注意范围的有效性。你已经在那里实例化了变量的新的a,b变体。你在欺骗自己相信那些变量是相同的。实际上他们在另一个地址空间。如果要使用类变量,则必须将参数取出到函数中。然后它们将与您所在的类同步,而不是将参数a,b隔离到函数范围内,