-1

It is clearly stated that interfaces don't have constructors. But when using anonymous inner classes we create an interface object and do overriding it methods. If there is no constructors in interfaces how this is possible. For an example,

interface A{
   void print();
}

class B{
   public static void main(String args[]){
       A a=new A(){
          void print(){
              System.out.println("Message");
          }
       };
   }
}

How that A a=new A() is possible if interface is not having constructors?

  • The anonymous inner class is the same as `class InternalNameWhoCares implements A` – Phil Aug 07 '18 at 06:22
  • 2
    The answer is in the question: It is is the constructor of the **anonymous inner class**, which implements the interface A. – JB Nizet Aug 07 '18 at 06:23

2 Answers2

2

The code

interface A {
    void print();
}

class B {
    public static void main(String[] args) {
        A a = new A() {
            public void print() {
                System.out.println("Message");
            }
        };
    }
}

is a shorthand for

interface A {
    void print();
}

class B {
    public static void main(String[] args) {
        class B$1 extends java.lang.Object implements A {
            B$1() {
                super();
            }
            public void print() {
                System.out.println("Message");
            }
        }
        A a = new B$1();
    }
}

With just one exception: If class B$1 is declared explicitly, it is possible to extend from it using class C extends B$1. However, it is not possible to extend from an anonymous class B$1 (JLS §8.1.4), even though it is not final (JLS §8.1.1.2).

That is, anonymous classes are still classes. As all classes (except java.lang.Object itself), even these classes extend java.lang.Object, directly or indirectly. If an anonymous class is specified using an interface, it extends java.lang.Object and implements that interface. If an anonymous class is specified using a class, it extends that class. In case the constuctor has arguments, the arguments are forwarded to super().

You can even (although definitely not recommended at all) insert a A a2 = new B$1(); later in main(), if you like. But really, don't do that, I'm just mentioning it to show what's going on under the hood.

You can observe this yourself by putting your source code in a separate directory, say, into AB.java, compile it, and then

  • look at the class files that were generated.
  • Use javap -c B$1 to see how the anonymous class was generated by javac.
Christian Hujer
  • 17,035
  • 5
  • 40
  • 47
  • I know it's just an example but shouldn't your `B$1` class definition be outside the `main` method? – Phil Aug 07 '18 at 06:33
  • @Phil Why should it be outside the `main` method? It's still a local class, after all, that is, a class declared in a method. Try adding a method `public void foo() { new B$1(); }` - if the class `B$1` is declared outside `main()`, method `foo()` would compile, if the class `B$1` is declared inside `main()`, method `foo()` will not compile. – Christian Hujer Aug 07 '18 at 06:35
  • Huh, TIL you can define classes within methods. – Phil Aug 07 '18 at 06:36
0

Every class has a default constructor which is the no-argument constructor if you don't define another constructor. And the anonymous class implement the interface will automatically generate it unless you define another constructor.

Jswq
  • 758
  • 1
  • 7
  • 23
  • 2
    This is not actually true. When creating an anonymous class instance, you have to invoke one of the constructors that is declared. Not all classes have default constructors. – Logan Aug 07 '18 at 06:31
  • @Logan Thank you. If there are no declared constructors it will use the default constructor, right? – Jswq Aug 07 '18 at 06:37
  • Yes, that is correct! – Logan Aug 07 '18 at 06:39