Essential Java Generics states that the output for this code:
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());
}
}
is:
public void Bar.foo(Bar)
public volatile void Bar.foo(java.lang.Object)
But when I compiled (1.7 compiler) and run the code, I have:
public void Bar.foo(Bar)
public void Bar.foo(java.lang.Object)
I re-compiled it using a 1.6 compiler. But my output is still the same.
The author’s exact quote is:
$ java Bar public void Bar.foo(Bar) public volatile void Bar.foo(java.lang.Object)
So it doesn’t seem like a typo error on his part.
What is causing the output to be different?
There is no such thing as a volatile method in Java. Only fields can be volatile.
See Why make a method volatile in java? for further details.
As the top answer there explains, the same bit mask (
0x00000040) is used for different purposes for fields and for methods. This confuses some older Java tools, causing them to incorrectly mark bridge methods asvolatile.In other words, there was a bug in the software that the blog writer was using at the time, causing the software to mistakenly include the
volatilein the printout. The bug got fixed, and you’re not seeing the erroneous modifier anymore.