2

I have been reading this guide on inner classes and came across this interesting example of an anonymous class.

So, by default we cannot instantiate an abstract class, e.g.

abstract class AnonymousInner {
   public abstract void mymethod();
}

public class Outer_class {
   public static void main(String args[]) {
      AnonymousInner inner = new AnonymousInner();
      inner.mymethod(); 
   }
}

Gives an error stating that we cannot instantiate an abstract class. But doing it this way is fine -

abstract class AnonymousInner {
   public abstract void mymethod();
}

public class Outer_class {
   public static void main(String args[]) {
      AnonymousInner inner = new AnonymousInner() {
         public void mymethod() {
            System.out.println("This is an example of anonymous inner class");
         }
      };
      inner.mymethod(); 
   }
}

So I am a bit lost how the second example is working.

Andronicus
  • 25,419
  • 17
  • 47
  • 88
RnD
  • 1,019
  • 5
  • 23
  • 49
  • 1
    In the 2nd example you are instantiating an ***implementation*** of the abstract class defined by provided antonymous inner class. – PM 77-1 Mar 07 '19 at 14:02

2 Answers2

3

It's because you're making an anonymous class - you're defining in place an implementation of your abstract class without a name, that can be used only here and then instantiating this (concrete) class. More about it here.

Other example would be using lambdas everywhere, where functional interface is needed, for example in streams:

stream.filter(a -> a.isTrue)...
// or
stream.filter(ClassA::isTrue)...

Here lambda and method reference are treated as implementations of Predicate.

Andronicus
  • 25,419
  • 17
  • 47
  • 88
3

Here, you are creating an object of the inner class that extends the abstract class. You can decompile the class file generated and see it for yourself.

This is the class that will be generated after the code compiles. (I've decompiled the class and it will look something like this :

final class Outer_class$1
  extends AnonymousInner
{
  public void mymethod()
  {
    System.out.println("This is an example of anonymous inner class");
  }
}

You can clearly see that the inner class is providing an implementation for the abstract class.

Nicholas K
  • 15,148
  • 7
  • 31
  • 57