2013-10-15 58 views
2

我與一個朋友發給我的代碼段相交。它有一個非常奇怪的行爲。我試圖谷歌代碼,看看我是否在互聯網上找到了一些東西,但沒有運氣。我無法聯繫我的朋友,所以我對自己的工作很感興趣。任何人都可以解釋爲什麼這段代碼返回false

public class Test { 

     public static void main(String[] args) throws MalformedURLException { 
      System.out.println(Boolean.TRUE); //This prints false 
     } 

     static { 
      try { 
       Field value = Boolean.class.getDeclaredField("value"); 
       value.setAccessible(true); 
       value.set(Boolean.TRUE, value.get(Boolean.FALSE)); 
      } catch (Exception e) { 
       throw new AssertionError(e); 
      } 
     } 

    } 

我認爲,這樣的一段代碼它聲明爲靜態的,它會首先運行該main方法,以及靜態代碼裏面正在改變這一切Boolean實例的值(?)。我不知道,我需要專家意見來證實這一點。

+0

「靜態」部分是一個靜態初始化塊,該類在第一次加載時執行。此塊使用(討厭)反射片將靜態字段「TRUE」的值更改爲「false」。看看[初始化字段](http://docs.oracle.com/javase/tutorial/java/javaOO/initial.html)瞭解更多詳情 – MadProgrammer

回答

4
Field value = Boolean.class.getDeclaredField("value"); 
value.setAccessible(true); 
value.set(Boolean.TRUE, value.get(Boolean.FALSE)); 

槽式反射的Boolean.TRUE恆定值設置爲Boolean.FALSE。這就是......正如你可以在代碼中讀到的一樣。

static初始化塊在main方法之前執行,不要讓命令欺騙你以爲它發生在稍後的時間。

報價從this後:

假設沒有安全管理器阻止您這樣做,你可以使用setAccessible來解決私人和重置修改擺脫最後,居然修改私有靜態最後領域。

+0

Okey,但不是'Boolean.TRUE'和' Boolean.FALSE'常量聲明爲'final'。那麼反射會欺騙'final'關鍵字? – 4gus71n

+0

反思是編程的祕訣:你可以完成不應該成爲可能的事情。 –

+0

是的,我意識到很多奇怪的事情。首先,這是因爲'Boolean.FALSE'和'Boolean.TRUE'都是布爾實例,而不是基元。如果你對基元嘗試這個例子,所有的都會正常運行。另外,布爾對象的'value'字段是'final',並且沒有被初始化,所以在某處有反射的同一個布爾類必須改變他自己的值字段值。男孩你是怪異的java [布爾.java](http://www.docjar。com/html/api/java/lang/Boolean.java.html) – 4gus71n

2

這是由於執行保證人的順序,靜態初始化塊將在類的實例的其他初始化之前執行。靜態初始化在類加載時完成;通常在班級的第一次參考。

由於在調用main方法之前,靜態塊會更改Boolean.TRUE的值,因此它會打印更改的值。

考慮下面的例子(source):

/* 
* Here we will learn to see how the different part (Ananymous Block, Constructor and Static Block) of class will behave 
* and what would be the order of execution. 
*/ 
class JBTCLass { 

    /* 
    * Here Creating the Ananymous Block 
    */ 
    { 
     System.out.println("Inside Ananymous Block"); 
    } 

    /* 
    * Now Creating the Static Block in Class 
    */ 
    static { 
     System.out.println("Inside Static Block"); 
    } 

    /* 
    * Here Creating the Constructor of Class 
    */ 
    JBTCLass() { 
     System.out.println("Inside Constructor of Class"); 
    } 

    public static void main(String[] args) { 

     // Creating the Object of the Class 
     JBTCLass obj = new JBTCLass(); 

     System.out.println("*******************"); 

     // Again Creating Object of Class 
     JBTCLass obj1 = new JBTCLass(); 

    } 

} 

結果:

Inside Static Block 
Inside Ananymous Block 
Inside COnstructor of Class 
******************* 
Inside Ananymous Block 
Inside COnstructor of Class 
1
public static final Boolean TRUE = new Boolean(true); 

常量TRUE是一個參考點到一個對象,最終意味着不能將它更改爲指向另一個對象。由於您已將value常數更改爲false,所以現在對象值爲false。

相關問題