2

Just today I needed a way to pass a function around between different objects. I quickly learned that you can't do that directly in Java, but you can pass around an instance of wht is apparently called an "anonymous inner class", like so:

To define the class:

interface MyCallback {
    public int execute(int i1, int i2);
}

To make an instance of it:

MyCallback callback = new MyCallback() {
    public int execute(int i1, int i2) {
        return i1 + i2;
    }
};

And to call it:

int sum = callback.execute(1, 2);  // Sets sum to 3.

Simple enough. But what I don't understand is why it is called "anonymous". Didn't I just give it the name MyCallback? And a thing that is named can't be anonymous, right? Please help me out of my confusion about this terminology.

Fuhrmanator
  • 11,459
  • 6
  • 62
  • 111
Andrejovich
  • 544
  • 2
  • 13
  • 1
    Try to print name of actual class of `callback`. You can get it via `callback.getClass().getName` and compare it with name of `MyCallback`. – Pshemo Feb 04 '14 at 16:34
  • @Pshemo my comment exactly in http://stackoverflow.com/a/21557857/1168342 – Fuhrmanator Feb 04 '14 at 18:20

5 Answers5

10

No, an anonymous class is a sub type of the type whose name you use to instantiate it.

An anonymous class declaration is automatically derived from a class instance creation expression by the Java compiler.

MyCallback is the name of the super type. Your anonymous sub class class has no name that is useful to the developer at compile time.

The actual class will have a name, something like MyCallback$1, but you won't be able to use it in the source code. For example, you can't do

MyCallback$1 anonymousClassInstance = ...;
Community
  • 1
  • 1
Sotirios Delimanolis
  • 274,122
  • 60
  • 696
  • 724
  • 2
    `but you won't be able to use it in the source code.` Actually with little help of reflection you can use it quite easy, but that is another story. +1 – Pshemo Feb 04 '14 at 16:29
  • 1
    @Pshemo I was trying to say that you can't use it as the declared type of a variable or a return type, etc. You can absolutely use it with reflection. – Sotirios Delimanolis Feb 04 '14 at 16:30
  • `System.out.println(callback.getClass().getName());` will show you the class' name. It will be something like `X$1` where `X` is the name of the class where you do the call to `new MyCallback` (likely not in an interface). – Fuhrmanator Feb 04 '14 at 16:40
  • *MyCallback is the name of the super type.* -- The Superclass of the object instantiated by the new is java.lang.Object (sysout of `callback.getClass().getSuperclass.getName()`). I think you meant to say that MyCallback is the interface (type). – Fuhrmanator Feb 04 '14 at 16:47
  • @Fuhrmanator Maybe I should have said _a super type_. The type of the anonymous class is derived from the name of the reference type used in the instance creation expression. If it is an interface type, then the anonymous class implements that interface. If it is a class type, the anonymous class extends that class. – Sotirios Delimanolis Feb 04 '14 at 16:50
4

didn't I just give it the name MyCallback?

No, you didn't: the name MyCallback belongs to the interface that you declared at the top. There could be only one type named MyCallback.

The class implementing MyCallback has no programmer-visible name (hence, it's called "anonymous"). However, the class has a name in bytecode, because JVM requires all classes to have a name. Generally, this hidden name is environment-specific. The compiler chooses it in a way to not collide with names of your other classes. For example, if you use Oracle's JVM on Windows, you could see the code for the anonymous classes generated in .class files with dollar signs and numbers in their name.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
3

No, you said that is an instance of the MyCallback() interface. The class which implements that interface, using the method logic you provided, is given a name on the fly, and it isn't a name you can really determine or use... so yes, as far as your source code is concerned, it really is anonymous.

(Typically the name is constructed by append a numeric suffix to the end of the name of the enclosing class -- but you have no way of knowing which suffix will be used, and not knowing the name is sufficiently anonymous for most uses of the word.)

keshlam
  • 7,931
  • 2
  • 19
  • 33
2

It's called anonymous, simply because it doesn't have a name.

In your case you're providing an implementation (subclass) of MyCallback, which is not named.

Konstantin Yovkov
  • 62,134
  • 8
  • 100
  • 147
0

An anonymous inner class would be

public class OuterClass
{
   public OuterClass()
   {
       MyCallback annoInnerClass = new MyCallback(){
             public int execute(int i1, int i2)
             {
                return i1 + i2;
             }
       };

        ....
   }
}

I you know Wicket, you know anonymous inner classes ;)

It's called anonymous, because you did not provide a name of the implementation of the class. It it called inner class, because you defined in inline.

Hannes
  • 2,018
  • 25
  • 32