4

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?

7
  • 1
    constructor being protected, not the class. Commented Jul 12, 2013 at 8:19
  • Sorry I should put the method call in the constructor. Commented Jul 12, 2013 at 8:19
  • possible duplicate of Can't access protected inner class while inheriting Commented Jul 12, 2013 at 8:25
  • It is because the protected class is visible, but the constructor is also protected and so the constructor is only visible to its direct subclasses, which MyClass is not. So you will have to make constructor public. Commented Jul 12, 2013 at 8:27
  • First you should write public class ClassInOtherPackage{} instead of public ClassInOtherPackage{}. Commented Jul 12, 2013 at 8:27

3 Answers 3

9

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.

Sign up to request clarification or add additional context in comments.

2 Comments

I just realized that this statement is ok --> MyClass.protectedInnerClass y; but not --> y = x.new protectedInnerClass(); Not sure why....
The class protectedInnerClass is accessible, but its constructor isn't.
5

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.

1 Comment

Thank you, in addition to johnchen902's answer, you answered with a solution that makes the concept clearer. In other words, if I have a public inner-class with a protected constructor, it won't work as well. Thank you for sharing the knowledge.
2

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 { } } 

2 Comments

My name doesn't follow the naming convention... it begins with lower case j.
Thank you so much. That makes me understand better now. Cheers!

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.