Essential Java Generics指出此代码的输出:
public interface Foo<T> {
void foo(T param);
}
public class Bar implements Foo<Bar> {
// This method will appear twice once with Object as parameter and once with Bar.
public void foo(Bar param) {
}
public static void main(String[] args) {
for (Method m : Bar.class.getMethods())
if (m.getName().startsWith("foo"))
System.out.println(m.toGenericString());
}
}
是:
public void Bar.foo(Bar)
public volatile void Bar.foo(java.lang.Object)
但是当我编译(1.7编译器)并运行代码时,我有:
public void Bar.foo(Bar)
public void Bar.foo(java.lang.Object)
我使用1.6编译器重新编译了它。但我的输出仍然是一样的。
作者的原话是:
$ java Bar public void Bar.foo(Bar) public volatile void Bar.foo(java.lang.Object)
所以这看起来不像是他的打字错误。
是什么导致输出不同?
最佳答案
Java 中不存在“ volatile ”方法。只有字段可以是 volatile 的。
参见Why make a method volatile in java?了解更多详情。
正如上面的答案所解释的,相同的位掩码(0x00000040
)用于字段和方法的不同目的。这会混淆一些较旧的 Java 工具,导致它们错误地标记 bridge methods作为 volatile
。
换句话来说,博客作者当时使用的软件存在一个错误,导致该软件错误地将 volatile
包含在打印输出中。 The bug got fixed ,并且您不会再看到错误的修饰符。
关于java - 编译器插入的方法(通过类型删除)是否是 volatile 的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10514162/