6

This one is weird. I have the following code:

class A
{   
    protected A clone() throws CloneNotSupportedException
    {
        return (A) super.clone();       
    }
}

when I de-compiled its bytecode through 'showmycode.com', it showed me the following code:

class A
{

    A()
    {
    }

    protected A clone()
    throws clonenotsupportedexception
    {
        return (A)super.clone();
    }

    protected volatile object clone()
    throws clonenotsupportedexception
    {
        return clone();
    }
}

What does it mean for a method return type to be volatile in the second 'clone' method? (This code was compiled through Eclipse's default JDK 1.6 compiler).

Gray
  • 115,027
  • 24
  • 293
  • 354
shrini1000
  • 7,038
  • 12
  • 59
  • 99

4 Answers4

8

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);
}
Gray
  • 115,027
  • 24
  • 293
  • 354
4

It doesn't mean anything. It is a bug in the decompiler. End of story.

(The bug is probably related to the fact that certain flag bits used in the class file format are "overloaded", meaning different things in the context of a class, field or method. I also vaguely recall that there have been some "new uses" in recent JVM spec revisions.)

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
4

The modifier mask for fields and methods is similar but not exactly the same. The decompiler is most likely using the toString method here

http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/lang/reflect/Modifier.java

but what it doesn't do is handle all bits

// Bits not (yet) exposed in the public API either because they
// have different meanings for fields and methods and there is no
// way to distinguish between the two in this class, or because
// they are not Java programming language keywords

What its doesn't handle is the bits which can mean synthetic and bridge which identify compiler generated code.

If volatile means anything at all here, it could mean don't remove the method even though it doesn't do anything.

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
  • It is not a bug. It seems that generated methods which are required for generics and are silently inserted in compiled classes, are marked "volatile", even if this is not their exact meaning. – Panayotis Aug 18 '16 at 15:08
1

It is a bug in your decompiler.

volatile is only a valid modifier for a field.

I recommend you to read this aricle.

aviad
  • 8,229
  • 9
  • 50
  • 98
  • 1
    I understand that. My question is: why does the decompiled code have 'volatile' in method signature *when the original code doesn't*? It seems that only bridge methods show this symptom. – shrini1000 Apr 29 '12 at 06:00
  • @shrini1000, try to compile your decompiled code - you will see that it does not compile. In java you cannot mark method with volatile modifier. I guess it is a bug of the tool you use for decompiling. – aviad Apr 29 '12 at 06:23