2013-03-15 170 views
3

我發現下面的代碼片段:奇怪的Java代碼

import java.lang.reflect.Field; 
public class Test { 
    public static void main(String[] args) { 
     System.out.println("Inside main"); 
    } 
    static { 
     try { 
      Field value = String.class.getDeclaredField("value"); 
      value.setAccessible(true); 
      value.set("Inside main", value.get("Inside static bolck")); 
     } catch (Exception e) { 
      throw new AssertionError(e); 
     } 
    } 
} 

按我的理解,輸出應爲Inside static bolck,但輸出當屬Inside statInside main相同字符長度。
*如果我增加Inside主長度,輸出長度也會增加。
任何人都可以請解釋嗎? 我對反思沒有太多的知識。

+0

它打印'裏面靜態bolck'我。你使用的是什麼版本的JDK/JRE? – assylias 2013-03-15 12:48:25

+0

IBM 32位SDK用於Windows,Java技術版,6版 – 2013-03-15 12:50:29

+1

我重複NPE的問題,因爲我渴望過 - ?**在任何情況下,你在哪裏與此打算** – mtk 2013-03-15 12:52:18

回答

4

在我的JDK上,String也有一個count成員,它需要更新以反映新的長度。

還有一個offset場,這可能會或可能不會需要更新(可能不在的情況下)。

最後,有一個hash字段,在您更改value之後將不再正確。

因爲這個代碼依賴於特定實現的String的無證細節,這是非常脆弱的,高度不可移植。例如(帽子@assylias),Oracle have removed the count and offset fields in JDK 7u6。如果你要從7u5升級到7u6,突然你的代碼會有不同的表現。

+1

計數在JDK 7u6中消失我認爲(對於Oracle JDK)。所以7更新6+它會工作,但它會像問題中的行爲。 – assylias 2013-03-15 12:50:16

+0

我找到了代碼片段。我對此沒有做任何事情。這僅僅是我的知識 – 2013-03-15 12:52:14

+2

它打印「內部統計」對我來說,這什麼@NPE說以上,這大概意味着OP在 – 2013-03-15 12:54:03

1

該代碼對String類的實際實現做出了假設,例如該類有一個名爲「值」的字段。

由於String類的內部狀態不是API或語言規範的一部分,實際執行將虛擬機之間不同廠商甚至來自相同供應商的不同VM版本之間變化或。

0

"Inside main"包含值11個字符[](值[]是在String類私有字段)
字符串value[]在其中限定字符串"Inside main"第一地方被初始化。 現在你正在改變value[]的值,它通過使用反射在字符串私有的實例變量,然後它從字符串Inside static bolck

0

只適合11字符的時候,你會改變‘內部主要’你被允許value.get()字符串< =「主內」 .Change - 「主內」向「內主(8位)」,並將其打印

"Inside static bolck"