This answer has already been covered in the question Why make a method volatile in java? But here's some more information.
When you overload methods (possibly only generic methods in the superclass), the method is marked as being a "bridge method". From java.lang.reflect.Modifier
:
static final int BRIDGE = 0x00000040;
Unfortunately, this is the same bit that is used to mark fields as being volatile
:
public static final int VOLATILE = 0x00000040;
If you print the modifiers on that method you will see something like:
public volatile
This is a limitation in the Modifiers.toString(int)
method that doesn't know if it is a field or method.
public static String toString(int mod) {
StringBuffer sb = new StringBuffer();
...
if ((mod & VOLATILE) != 0) sb.append("volatile ");
// no mention of BRIDGE here
...
return sb.toString().substring(0, len-1);
}