不同的 Java 编译器为同一个匿名类生成不同的类名

Different Java compilers generate different class names for the same anonymous class

提问人:WilliW 提问时间:3/21/2023 更新时间:3/21/2023 访问量:57

问:

匿名类的名称是通过将外部类名与 a 和数字连接起来生成的,因此例如,类中的匿名类可以生成为 、 等。$FooFoo$1Foo$2

我的经验是,Eclipse编译器和JDK编译器(都设置为与Java 8兼容)以不同的方式生成数字部分,即在Eclipse和javac中相同的匿名类。Foo$2Foo$6

这种行为是否得到 Java 标准的支持?

背景: 匿名类的实例以块的形式存储到文件中,并作为标识符。假设类名生成在不同的编译器实现中是一致的。但是,根据使用的编译器,我会得到不同的结果,并且我无法可靠地读回使用不同实现写入的数据。instance.getClass().getName()

Java 匿名类

评论

3赞 knittl 3/21/2023
即使更改方法/代码的顺序也会导致类名更改。如果需要稳定名称,请使用命名类
1赞 Gray 3/21/2023
我怀疑语言标准根本没有提到这个自动生成的名称,而是将它们留给编译器。你得到不同数字的原因是,你创建的匿名类型可能比你想象的要多——特别是考虑到标准的 Java 8 模式。

答:

2赞 Thomas Kläger 3/21/2023 #1

Java 语言规范 (13.1.The Form of a Binary)对匿名类的二进制名称是这样说的:

匿名类的二进制名称 (§15.9.5) 由其直接封闭类型的二进制名称组成,后跟 $,后跟非空数字序列。

它根本没有说明这些数字有任何意义 - 为了满足 Java 语言规范的要求,编译器可以使用随机数,这些随机数会随着每次编译而变化。

因此,依赖这些数字的特定值就像依赖 HashMap 中键的顺序一样 - 它有时和特殊情况下可以工作,但如果你想要强大的软件,你就不能依赖它。