Unable to Access Anonymous Class Method in Java

1.3k views Asked by At

I receive a compiler error whenever I attempt to invoke a method belonging to an anonymous class from the outer class. Example:

public class Test {

    public static void main(String[] args) {
        Test testObj = new Test(){
            public void doStuff(){
                System.out.println("Test");
            }
        };
        testObj.doStuff();
    }
}

The error the compiler provides is simply "Cannot find symbol - doStuff()". I must be overlooking something...any ideas?

Thanks in advance.

5

There are 5 answers

4
Naman Gala On BEST ANSWER

You can only call existing method from the Reference of Test class. So if you have declared doStuff() method then only you can call it with Test testObj reference.

See this SO question Is it possible to call subclasses' methods on a superclass object?

But you can surely call new method inside other method declaration of anonymous class. See below example.

Example:

public class Test {
    public void doStuff() {
        System.out.println("Test");
    }

    public static void main(String[] args) {
        Test testObj = new Test() {
            public void doStuff() {
                System.out.println("Inside anonymous class doStuff");
                doOtherStuff(); // calling new method doOtherStuff() and it works
            }

            public void doOtherStuff() {
                System.out.println("Inside anonymous class doOtherStuff");
            }
        };
        testObj.doStuff();

        /*Below code give compilation error: The method doOtherStuff() is undefined for the type Test*/
        // testObj.doOtherStuff();
    }
}

Output:

Inside anonymous class doStuff
Inside anonymous class doOtherStuff
0
Thilo On

Java is a typesafe language. When you have an object of class Test (which you declared testObj to be), the compiler will only let you call methods that are defined in class Test. Even if you have an instance of a subclass, the compiler won't infer that automatically, so it won't let you call subclass methods. It only goes by the type of the variable.

You need to define the doStuff method in your Test class.

Of course, this makes it silly to subclass it anonymously, unless you want to override the method to do something else.

0
Hovercraft Full Of Eels On

The problem boils down to essentially, what is the difference between a reference variable and an object. The testObj variable is Test type, and Test has no doStuff method, only your anonymous class does, but while the compiler can create an object of the anonymous type, it can't create a variable of the anonymous type. The bottom line is that you shouldn't use anonymous types for this type of code, code where the child class has methods that are not within the parent class. Instead either give the parent class the method (here give Test the doStuff method) or consider using a private inner class in place of your anonymous class.

2
dkatzel On

The Test class doesn't have a method doStuff(). When you made your anonymous class you added a new method named doStuff(). You then store that reference as a Test type which then can't access the extra method.

Why are you using an anonymous class like that?

The simplest way is to just add the doStuff() method to test

public class Test {

     public void doStuff(){
          System.out.println("Test");
     }

    public static void main(String[] args) {
        Test testObj = new Test();
        testObj.doStuff();
    }
}
0
Erwin Bolwidt On

The problem is that an anonymous class has no type name (that's why it's called anonymous).

You assigned your anonymous class instance to a variable of type Test, and the Test type has no method named doStuff.

So you cannot assign an anonymous class instance to any variable and then call a method on it that is not defined in a superclass.

It is possible to call the method though, if you do not assign it:

public class Test {

    public static void main(String[] args) {
        new Test(){
            public void doStuff(){
                System.out.println("Test");
            }
        }.doStuff();
    }
}

Note that there are few situations in which this is useful in a real-world Java program.

I'm just showing this to highlight the source of the problem: anonymous classes are certainly allowed to have methods that are not defined in a superclass, and the only reason that you cannot easily invoke them is because the type of the class is anonymous (doesn't have a name). But they still exist and can be invoked directly on the instance.