简体   繁体   中英

Protected inner-class is NOT accessible from subclass of another package

I have the following code in 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.
  }
}

Refer to the Java documentation:

"The protected modifier specifies that the member can only be accessed within its own package (as with package-private) and, in addition, by a subclass of its class in another package."

Why can't I instantiate the inner protected class as shown above?

In JLS 8.8.9

8.8.9. Default Constructor

... if the class is declared protected , then the default constructor is implicitly given the access modifier protected ( §6.6 ); ...

So the implicitly declared constructor is:

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

You code won't compile because the constructer is inaccessible.

The default constructor of protectedInnerClass is protected , not the class . You need to define a public constructor to your inner class :

protected class protectedInnerClass {

  public protectedInnerClass () {}

}

MyClass can access the protected members of ClassInOtherPackage , but it cannot access the protected members of protectedInnerClass , since its constructor is protected hence you get such a compilation error.

As johnchen902 said the default constructor of a protected class is implicitly protected. Protected means that only subclasses and classes within the same package can access it.

  1. The protectedInnerClass doesn't declare a constructor thus it is implicitly protected.
  2. MyClass is not a subclass of protectedInnerClass, thus it can not access it.

So you have to make it public or you can modify your code like this:

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 {

    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM