2012-04-29 4 views
6

Questo è strano. Ho il seguente codice:'volatile' nella firma del metodo?

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

quando de-compilato il suo bytecode tramite 'showmycode.com', mi ha mostrato il seguente codice:

class A 
{ 

    A() 
    { 
    } 

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

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

Che cosa significa per un tipo di metodo di ritorno essere volatili nel secondo metodo "clone"? (Questo codice è stato compilato tramite il compilatore JDK 1.6 predefinito di Eclipse).

+5

penso che questa risposta si applica qui: http://stackoverflow.com/questions/6651867/why-make-a-method-volatile-in-java –

+0

@bunting thx. Potresti pl.menzionarlo nella tua risposta così posso accettarlo? – shrini1000

risposta

4

La maschera di modifica per campi e metodi è simile ma non esattamente la stessa. Il Decompiler è più probabile con il metodo toString qui

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

ma quello che non fa è di gestire tutti i bit

// 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 

ciò che il suo non gestisce è il bit che può significare synthetic e bridge che identificano il codice generato dal compilatore.

Se volatile significa qualcosa qui, potrebbe significare non rimuovere il metodo anche se non fa nulla.

+0

Non è un bug. Sembra che i metodi generati che sono richiesti per i generici e che siano inseriti silenziosamente in classi compilate, siano contrassegnati come "volatili", anche se questo non è il loro significato esatto. – Panayotis

1

Si tratta di un bug nel decompilatore.

volatile è solo un modificatore valido per un campo.

Vi consiglio di leggere l'articolo this.

+1

Lo capisco. La mia domanda è: perché il codice decompilato ha 'volatile' nella firma del metodo * quando il codice originale non *? Sembra che solo i metodi bridge mostrino questo sintomo. – shrini1000

+0

@ shrini1000, prova a compilare il codice decompilato: vedrai che non viene compilato. In java non puoi contrassegnare il metodo con il modificatore volatile. Immagino sia un bug dello strumento che usi per decompilare. – aviad

4

Non significa niente. È un bug nel decompilatore. Fine della storia.

(Il bug è probabilmente correlato al fatto che alcuni bit di flag utilizzati nel formato di file di classe sono "sovraccaricati", ovvero cose diverse nel contesto di una classe, un campo o un metodo.Vedo anche vagamente che ci sono stati alcuni "nuovi usi" nelle recenti revisioni di specifiche JVM.)

8

Questa risposta è già stata illustrata nella domanda Why make a method volatile in java? Ma ecco alcune ulteriori informazioni.

Quando si sovraccaricano metodi (probabilmente solo metodi generici nella superclasse), il metodo è contrassegnato come "bridge method". Da java.lang.reflect.Modifier:

static final int BRIDGE = 0x00000040; 

Purtroppo, questo è lo stesso bit che viene utilizzato per contrassegnare i campi come volatile:

public static final int VOLATILE   = 0x00000040; 

Se si stampano i modificatori su quel metodo si vedrà qualcosa di simile:

public volatile 

Questa è una limitazione nel metodo Modifiers.toString(int) che non sa se si tratta di un campo o di un metodo.

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); 
}