受保护的内部类不能从另一个包的子类访问

时间:2013-07-12 08:16:47

标签: java subclass inner-classes

我在Java中有以下代码:

package a;
public classs ClassInOtherPackage{
    protected void protectedMethod(){}
     protected class protectedInnerClass {}
}

package b;
import a.*;
public class MyClass extends ClassInOtherPackage{
  public MyClass(){
    MyClass x = new MyClass();
    x.protectedMethod();  //<-- This one ok
    //UPDATED: Declaration is ok
    MyClass.protectedInnerClass y; //<-- This one ok
    //UPDATED: Only when instantiated is not allowed, why?
    y = x.new protectedInnerClass(); //<-- Not allow when instantiated.
  }
}

请参阅Java文档:

  

“protected modifier指定只能访问该成员   在它自己的包中(与package-private一样),另外,通过   另一个包中其类的子类。“

为什么我不能实例化如上所示的内部受保护类?

3 个答案:

答案 0 :(得分:8)

JLS 8.8.9

  

8.8.9。默认构造函数

     

...如果声明了类protected,则默认构造函数被隐式赋予访问修饰符protected§6.6); ...

所以隐式声明的构造函数是:

protected class protectedInnerClass {
    protected protectedInnerClass(){
        super();
    }
}

您的代码无法编译,因为构造函数不可访问。

答案 1 :(得分:3)

protectedInnerClass的默认构造函数是protected,而不是类。您需要为内部类定义public构造函数:

protected class protectedInnerClass {

  public protectedInnerClass () {}

}

MyClass可以访问protected ClassInOtherPackage成员,但无法访问protected protectedInnerClass成员,因为其构造函数为protected因此你得到这样的编译错误。

答案 2 :(得分:2)

正如johnchen902所说,受保护类的默认构造函数是隐式保护的。 受保护意味着只有同一个包中的子类和类才能访问它。

  1. protectedInnerClass不声明构造函数,因此它是隐式保护的。
  2. MyClass不是protectedInnerClass的子类,因此无法访问它。
  3. 所以你必须公开它,或者你可以像这样修改你的代码:

    public class MyClass extends ClassInOtherPackage {
    
        public MyClass() {
            MyClass x = new MyClass();
            x.protectedMethod(); // <-- This one ok
            MyClass.protectedInnerClass y = x.new MyProtectedInnerClass();
        }
    
        protected class MyProtectedInnerClass extends protectedInnerClass {
    
        }
    }