Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Accessing protected method of anonymous object vs by a named reference

Say I have this abstract class:

package test.one;

public abstract class One {
  
  protected abstract void whatever();

  public void run(){
    whatever();
  }
  
}

And use it like this:

package test.two;

import test.one.One;

public class Three {

  public static void main(String[] args){
    One one = new One(){
      @Override
      protected void whatever(){
        System.out.println("Do whatever..");
      }
    };
    one.whatever();
  }

}

This code fails on compilation which is pretty much expected.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

test/two/Three.java:14: error: whatever() has protected access in One
    one.whatever();
       ^
1 error

But the below code compiles successfully which seems surprisingly:

package test.two;

import test.one.One;

public class Two {

  public static void main(String[] args){
    new One(){
      @Override
      protected void whatever(){
        System.out.println("Do whatever..");
      }
    }.whatever();
  }

}

The difference is that in the latter case I’m accessing the method without a named reference. Why does the compiler allow such access?

>Solution :

The difference is that in the latter case I’m accessing the method without a named reference. Why does the compiler allow such access?

No, the difference is that in the latter case you’re accessing the method on the anonymous class rather than on a reference of type One.

Leaving aside the oddities around protected access, you can see the difference very easily by just creating an anonymous class with a public method:

class Test {
    public static void main(String[] args) {
        // This is fine...
        new Object() {
            public void method() {
                System.out.println("Called");
            }
        }.method();
        
        // This is not, because Object doesn't contain a method called "method".
        Object o = new Object() {
            public void method() {
                System.out.println("Called");
            }
        };
        o.method();        
    }
}

As noted in comments, another way to see the same effect is to use var, so that the compile-time type of the variable is the anonymous class.

Even private members within anonymous classes can be accessed within the containing scope, just as if they were normal nested classes.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading