2

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)

因此,这似乎不是他的拼写错误。

是什么导致输出不同?

4

1 回答 1

7

Java 中不存在 volatile 方法。只有字段可以是可变的。

请参阅为什么在 java 中使方法易变?了解更多详情。

正如上面的答案所解释的那样,相同的位掩码 ( 0x00000040) 用于字段和方法的不同目的。这会混淆一些较旧的 Java 工具,导致它们错误地将桥接方法标记为volatile.

换句话说,博客作者当时使用的软件存在错误,导致该软件错误地将 包含volatile在打印输出中。该错误已修复,您不再看到错误的修饰符。

于 2012-05-09T10:23:26.147 回答