2012-04-29 57 views
6

這個很奇怪。我有以下代碼:方法簽名中'volatile'?

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

通過「showmycode.com」當我去編譯它的字節碼,它給我下面的代碼:

class A 
{ 

    A() 
    { 
    } 

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

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

是什麼意思一個方法的返回類型在第二種「克隆」方法中是不穩定的? (這段代碼是通過Eclipse的默認JDK 1.6編譯器編譯的)。

+5

我想這個答案在這裏適用:http://stackoverflow.com/questions/6651867/why-make-a-method-volatile-in-java – 2012-04-29 06:05:42

+0

@bunting THX。你可以套住嗎?在你的回答中提到它,所以我可以接受它? – shrini1000 2012-04-29 06:07:57

回答

4

字段和方法的修飾符掩碼相似但不完全相同。反編譯是最有可能使用的方法toString這裏

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

,但它沒有做到的是處理所有位

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

什麼它不處理是可以的意思synthetic位和bridge,它們標識編譯器生成的代碼。

如果volatile在這裏意味着什麼,它可能意味着即使它沒有做任何事情也不會刪除該方法。

+0

這不是一個錯誤。看起來,泛型所需的生成方法被靜默地插入編譯類中,但它們被標記爲「易失性」,即使這不是它們的確切含義。 – Panayotis 2016-08-18 15:08:19

1

這是您的反編譯器中的一個錯誤。

volatile只是一個字段的有效修飾符。

我建議您閱讀this文章。

+1

我明白這一點。我的問題是:當原始代碼沒有*時,爲什麼反編譯的代碼在方法簽名中有'volatile'?似乎只有橋樑方法才能顯示這種症狀。 – shrini1000 2012-04-29 06:00:36

+0

@ shrini1000,嘗試編譯你的反編譯代碼 - 你會看到它不能編譯。在Java中,你不能用volatile修飾符標記方法。我想這是您用於反編譯的工具的一個錯誤。 – aviad 2012-04-29 06:23:09

4

這並不意味着什麼。這是反編譯器中的一個錯誤。故事結局。 (這個錯誤可能與類文件格式中使用的某些標誌位是「重載」的事實有關,這意味着在類,字段或方法的上下文中有不同的事情,我還隱約回憶起已經存在在最近的JVM規格修訂中有一些「新用途」。)

8

此問題已被覆蓋在問題Why make a method volatile in java?但這裏有一些更多的信息。

當您重載方法(可能只有超類中的泛型方法)時,該方法被標記爲"bridge method"。從java.lang.reflect.Modifier

static final int BRIDGE = 0x00000040; 

不幸的是,這是用來領域標記爲volatile同位:

public static final int VOLATILE   = 0x00000040; 

如果您打印該方法的修飾,你會看到類似這樣的:

public volatile 

這是Modifiers.toString(int)方法中的一個限制,它不知道它是否是字段或方法。

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