【问题标题】:Type of anonymous type匿名类型的类型
【发布时间】:2011-12-02 10:59:16
【问题描述】:

这是我遇到的一件有趣的小事。我在搞乱匿名类型,我写了类似的东西:

public class Test {
    public static void method(Object obj) {
        System.out.println(obj.getClass().getName());
    }

    public static void main(String[] args) {
        method(new Object() {
           int n = 0; 
        });
    }
}

好吧,当打印的结果实际上是 test.Test$1 这是定义匿名对象的类的名称时,我感到非常惊讶(如果您将打印类型名称的方法移动到另一个,它仍然是相同的班级)。

有人可以解释这种行为吗?这是 Java 标准中指定的还是另一种“未定义的行为”?

【问题讨论】:

  • 您究竟关心哪种行为?
  • 这实际上是一种众所周知的行为。匿名类也有名称,因为编译器需要以某种方式了解这些类型......
  • undefined behavior in java

标签: java oop class


【解决方案1】:

如果你再看一遍,你会发现打印出来的类名后面有一个$1。内部类总是通过将$ 和内部类名称连接到包含类的名称来命名。匿名类只是得到一个数字而不是一个名字。如此有效,打印出来的类名是“test.Test 中包含的第一个匿名类”。

【讨论】:

    【解决方案2】:

    它正在打印使用new Object() { ... } 创建的匿名类的名称,它按预期工作。基本上,您已经扩展 Object 以创建一个新类(及其实例)而不命名它,因此 jvm 自动将其命名为封闭类,后跟 $ 和一个索引

    【讨论】:

      【解决方案3】:

      test.Test$1 与 test.Test 不同。例如,如果你声明一个内部类型:

      public class Test {
          // ...
          private class Foo {};
      }
      

      那么 Foo 的限定名称将是 test.Test$Foo。 $1 表示“在 test.Test 中声明的第一个匿名类型”。

      【讨论】:

        【解决方案4】:

        是的,这是公认的行为。嵌套类始终表示为 package.outer class$nested class。例如test.Test$NestedTest,用于“test”包中“Test”类中​​的嵌套类“NestedTest”。

        匿名类仅按定义顺序编号(因为它们没有名称)。例如,

        public static void main(String[] args) {
            method(new Object() {
                int n = 0;
            });
        
            Object m = new Test() {
                int n = 0;
            };
        
            method(new Object() {
                int m = 0;
            });
        
            method(m);
            method(m);
            method(m);
        }
        

        会显示

        Test$1
        Test$3
        Test$2
        Test$2
        Test$2
        

        好问题!

        【讨论】:

          【解决方案5】:

          当您使用语法new SomeClass() { ... } 时,您将创建一个匿名 类。 Java 将匿名类命名为<containing class>$number,其中number 是匿名类在包含类中出现的从1 开始的基数。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2016-01-30
            • 2010-09-28
            • 2013-08-02
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多