【问题标题】:How interfaces create objects when using at anonymous inner classes [duplicate]在匿名内部类中使用时接口如何创建对象[重复]
【发布时间】:2018-08-07 06:19:23
【问题描述】:

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

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() 怎么可能?

【问题讨论】:

  • 匿名内部类同class InternalNameWhoCares implements A
  • 答案在问题中:是匿名内部类的构造函数,实现了接口A。

标签: java constructor


【解决方案1】:

代码

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

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

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

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

【讨论】:

  • 我知道这只是一个示例,但您的 B$1 类定义不应该在 main 方法之外吗?
  • @Phil 为什么应该在main 方法之外?毕竟还是本地类,也就是方法中声明的类。尝试添加一个方法public void foo() { new B$1(); } - 如果类B$1main() 之外声明,则方法foo() 将编译,如果类B$1main() 内声明,则方法foo() 将无法编译。
  • 嗯,你可以在方法中定义类。
【解决方案2】:

每个类都有一个默认构造函数,如果你不定义另一个构造函数,它就是无参数构造函数。并且实现接口的匿名类会自动生成,除非你定义另一个构造函数。

【讨论】:

  • 这不是真的。创建匿名类实例时,您必须调用已声明的构造函数之一。并非所有类都有默认构造函数。
  • @Logan 谢谢。如果没有声明的构造函数,它将使用默认构造函数,对吗?
  • 是的,没错!
猜你喜欢
  • 2010-12-30
  • 1970-01-01
  • 2014-12-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-06
  • 2016-01-30
  • 1970-01-01
相关资源
最近更新 更多