java - 编译器插入的方法(通过类型删除)是否是 volatile 的?

标签 java debugging generics reflection

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/

相关文章:

java - List<T> 返回一个对象集合

java - Ant/JUnit - 如何断言包依赖项/非依赖项?

c++ - 调试断言失败 : _CrtIsValidHeapPointer(block)

python - 如何让 Perl 和 Python 打印正在执行的程序的每一行?

ios - 调试扩展时如何打印变量?

Java 通用问题 : Any better way?

c# - .NET Generic 集合在多线程环境中是否更慢

java - JPA manytoone关系删除操作

java - 膨胀类 fragment 谷歌地图时出错

java - InputStream的AudioInputStream(从资源目录加载)