首页 > 解决方案 > 在匿名内部类中使用时接口如何创建对象

问题描述

明确指出接口没有构造函数。但是当使用匿名内部类时,我们会创建一个接口对象并覆盖它的方法。如果接口中没有构造函数,这怎么可能。例如,

interface A{
   void print();
}

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

如果接口没有构造函数,那 A a=new A() 怎么可能?

标签: javaconstructor

解决方案


编码

interface A {
    void print();
}

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

是的简写

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();
    }
}

只有一个例外:如果类B$1被显式声明,则可以使用class C extends B$1. 但是,不能从匿名类扩展B$1(JLS §8.1.4),即使它不是final(JLS §8.1.1.2)。

也就是说,匿名类仍然是类。与所有类(除了java.lang.Object它自己)一样,甚至这些类也直接或间接地扩展java.lang.Object。如果使用接口指定匿名类,它会扩展java.lang.Object并实现该接口。如果使用类指定匿名类,它会扩展该类。如果构造函数有参数,则将参数转发到super().

如果您愿意,您甚至可以(尽管绝对不推荐)A a2 = new B$1();稍后插入。main()但实际上,不要那样做,我只是提到它以显示引擎盖下发生的事情。

您可以通过将源代码放在单独的目录中来自己观察这一点,例如 into AB.java,编译它,然后

  • 查看生成的类文件。
  • 用于javap -c B$1查看匿名类是如何由javac.

推荐阅读