java - Java 匿名类是在运行时创建的吗?

标签 java compiler-construction runtime anonymous-class

匿名 Java 类是在运行时创建的还是由编译器提前创建的?

根据 Java 文档,它们类似于本地类,只是它们没有名称,所以我猜测它们是提前创建的。如果您可以引用您的来源或知道如何测试这样的事情,请告诉我!

最佳答案

它们是由编译器创建的。您可以通过编译一些代码并查看磁盘上的内容来查看它们。您最终会得到类似 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
}

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

这并不是说生成的类没有名称,真的 - 只是它是一个强烈建议不要用于手动代码的名称。来自 JLS 3.8:

The "Java letters" include uppercase and lowercase ASCII Latin letters A-Z (\u0041-\u005a), and a-z (\u0061-\u007a), and, for historical reasons, the ASCII underscore (_, or \u005f) and dollar sign ($, or \u0024). The $ sign should be used only in mechanically generated source code or, rarely, to access pre-existing names on legacy systems.

因此理论上您可以访问源代码中的 Test$1 - 但 javac 似乎以我没有的方式阻止您这样做还没想明白。 (我认为它使用类文件中的元数据来检查它是否是从匿名内部类编译的。)从语言的角度来看,这使得它“或多或少”是匿名的。

关于java - Java 匿名类是在运行时创建的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24818536/

相关文章:

unity-game-engine - 创建游戏对象的副本

java - 如何将不同的菜单项添加到多个上下文菜单?

java - 使用 Grizzly 作为 Web 服务引擎

macos - 如何在 OS X 上轻松安装 arm-elf-gcc?

c++ - g++ 尝试(失败)为共享对象静态链接到 libstdc++

objective-c - 如何覆盖框架类(运行时)中的方法

java - 为什么 getThreadAllocatedBytes 不一致?

java - Java Set 没有随机访问方法

java - 如何在 Angular 7 中使用字符串添加动态查询参数?

c++ - 可以读取目标文件吗?