3

我在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 文档:

“受保护的修饰符指定该成员只能在其自己的包中访问(与包私有一样),此外,它的类在另一个包中的子类也可以访问。”

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

4

3 回答 3

8

JLS 8.8.9中

8.8.9。默认构造函数

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

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

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

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

于 2013-07-12T08:23:46.547 回答
3

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

protected class protectedInnerClass {

  public protectedInnerClass () {}

}

MyClass可以访问 的protected成员ClassInOtherPackage,但不能访问 的protected成员protectedInnerClass,因为它的构造函数protected因此会出现这样的编译错误。

于 2013-07-12T08:26:14.270 回答
2

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

  1. protectedInnerClass 没有声明构造函数,因此它是隐式保护的。
  2. MyClass 不是 protectedInnerClass 的子类,因此它不能访问它。

因此,您必须将其公开,或者您可以像这样修改您的代码:

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 {

    }
}
于 2013-07-12T08:30:57.680 回答