使用受保护的构造函数对类进行匿名初始化

时间:2015-01-21 17:15:37

标签: java initialization anonymous

我们假设我们有一个班级:

public class SomeClass {    
    protected SomeClass () { 
    }
}

在位于不同包中的MainClass中,我尝试执行两行:

public static void main(String[] args) {
    SomeClass sac1 = new SomeClass(); 
    SomeClass sac2 = new SomeClass() {}; 
}

由于protected构造函数,在这两种情况下我都希望程序失败。令我惊讶的是,匿名初始化工作正常。有人可以解释一下为什么第二种初始化方法可以吗?

4 个答案:

答案 0 :(得分:9)

您的匿名课程

SomeClass sac2 = new SomeClass() {}; 

基本上变成了

public class Anonymous extends SomeClass {
    Anonymous () {
        super();
    }
}

构造函数没有访问修饰符,因此您可以在同一个包中无问题地调用它。您还可以调用super(),因为可以从子类构造函数访问protected父构造函数。

答案 1 :(得分:3)

第一行失败,因为SomeClass的构造函数是protectedMainClass不在SomeClass的包中,并且它不是子类{{1 }}

第二行成功,因为它正在创建MainClass的匿名子类。这个匿名内部类是SomeClass的子类,因此它可以访问SomeClass的{​​{1}}构造函数。此匿名内部类的默认构造函数隐式调用此超类构造函数。

答案 2 :(得分:2)

中的那两个小括号
SomeClass sac2 = new SomeClass() {};

在Java中调用了很多自动行为。以下是执行该行时会发生的情况:

  1. 创建了SomeClass的匿名子类。
  2. 该匿名子类被赋予一个默认的无参数构造函数,就像声明没有无参数构造函数的任何其他Java类一样。
  3. 使用visibility public
  4. 定义默认的无参数构造函数
  5. 默认的无参数构造函数被定义为调用super()(这是no-arg构造函数总是首先执行的操作)。
  6. new命令调用此匿名子类的无参构造函数,并将结果分配给sac2
  7. SomeClass的匿名子类中的默认无参数构造函数可以访问protected的{​​{1}}构造函数,因为匿名子类是SomeClass的后代,所以对SomeClass的调用有效。 super()语句调用此默认的无参数构造函数,该构造函数具有new可见性。

答案 3 :(得分:0)

你的行

SomeClass sac2 = new SomeClass() {};

创建一个扩展SomeClass的新类的实例。由于SomeClass定义了一个没有参数的受保护构造函数,因此子类可以在它自己的构造函数中隐式调用它,这在这一行中发生。