是否在运行时创建了Java匿名类?

Dai*_*run 2 java compiler-construction runtime anonymous-class

是否在编译时在运行时或提前创建了匿名Java类?

根据Java文档,They are like local classes except that they do not have a name所以我的猜测是它们是提前创建的.如果你能引用你的消息来源或知道如何测试这样的东西,请告诉我!

Jon*_*eet 11

它们是由编译器创建的.您只需编译一些代码并查看磁盘上的内容即可看到它们.你会得到像包含匿名方法的类Foo$1.class在哪里的东西Foo.

例如:

public class Test {
    public static void main(String[] args) {
        Runnable runnable = new Runnable() {
            @Override public void run() {
                System.out.println("Hi");
            }
        };
    }
}

> javac Test.java
> dir Test*.class
Test.class
Test$1.class

> javap -c Test$1

Compiled from "Test.java"
final class Test$1 implements java.lang.Runnable {
  Test$1();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return

  public void run();
    Code:
       0: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
       3: ldc           #3                  // String Hi
       5: invokevirtual #4                  // Method java/io/PrintStream.println[...]
       8: return
}
Run Code Online (Sandbox Code Playgroud)

就JVM而言,它们只是普通的类.编译器添加的各种语言功能(例如相关的编码实例)是通过额外的方法,构造函数参数和通过使用您无法引用的名称有效隐藏的字段实现的.

并不是生成的类没有名称,实际上 - 只是它是一个强烈不鼓励手动代码的名称.来自JLS 3.8:

"Java字母"包括大写和小写ASCII拉丁字母AZ(\ u0041-\u005a)和az(\ u0061-\u007a),并且由于历史原因,ASCII下划线(_,或\ u005f)和美元符号($,或\ u0024).$符号应仅用于机械生成的源代码,或者很少用于访问旧系统上的预先存在的名称.

所以理论上你可以访问Test$1源代码 - 但javac似乎阻止你这样做,我还没有深思熟虑.(我认为它使用类文件中的元数据来检查它是否是从匿名内部类编译的.)这使得它从语言角度"或多或少"匿名.