2011-11-16 62 views
0

以下程序正在訪問和修改類SimpleKeyPair中聲明的名爲privateKey的私有字段。讓我們來看看它。通過使用Java中的反射訪問和修改私有類成員

package mod; 

import java.lang.reflect.Field; 
import java.util.logging.Level; 
import java.util.logging.Logger; 

final class SimpleKeyPair 
{ 
    private String privateKey = "Welcome SimpleKeyPair "; 
} 

final public class Main 
{ 
    public static void main(String[] args) 
    { 
     SimpleKeyPair keyPair = new SimpleKeyPair(); 
     Class c = keyPair.getClass(); 

     try 
     { 
      Field field = c.getDeclaredField("privateKey"); // gets the reflected object 
      field.setAccessible(true); 

      System.out.println("Value of privateKey: " + field.get(keyPair)); // displays 「Welcome SimpleKeyPair" 

      field.set(keyPair, "Welcome PrivateMemberAccessTest"); // modifys the private member varaible 

      System.out.println("Value of privateKey: " + field.get(keyPair)); 
     } 
     catch (IllegalArgumentException ex) 
     { 
      Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex); 
     } 
     catch (IllegalAccessException ex) 
     { 
      Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex); 
     } 
     catch (NoSuchFieldException ex) 
     { 
      Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex); 
     } 
     catch (SecurityException ex) 
     { 
      Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex); 
     } 
    } 
} 

在上面的代碼中,類SimpleKeyPair中聲明的私人領域privateKey正在被訪問,並通過下面的語句顯示在控制檯上。

Field field = c.getDeclaredField("privateKey"); 
field.setAccessible(true); 
System.out.println("Value of privateKey: " + field.get(keyPair)); 

和該字段被修改,並通過下列說法正在顯示該字段的新值。

field.set(keyPair, "Welcome PrivateMemberAccessTest"); 
System.out.println("Value of privateKey: " + field.get(keyPair)); 

該方案的實際輸出將如下。

Value of privateKey: Welcome SimpleKeyPair 
Value of privateKey: Welcome PrivateMemberAccessTest 

意思是說,在Java中使用反射允許私人資源的直接訪問。如果是這樣的話,聲明一個成員爲私人自己在Java中是不安全的,雖然宣稱集體成員爲私人的目的之一是將其隱藏在世界之外。 Java中反射的實際用法是什麼?

回答

5

反射可以允許訪問某個類的私有(以及包和受保護的)作用域成員,這是正確的。但是,如果您閱讀JavaDocs,則會發現在執行請求的操作之前,所有獲取和調用這些訪問器的方法都會執行SecurityManager檢查。因此,在具有SecurityManger的環境中,操作將失敗,並引發SecurityExceptions。

1

反射的用途是什麼?自省,製作動態電話/決議,工具等的能力。

你的意思是什麼private的實際使用?宣佈意圖,並且不允許濫用私人會員。嘿。

+0

這是否意味着'SecurityManager'只能阻止*隨便*濫用私人成員?如果是這樣,我想引用。 – meriton

+1

@meriton假設沒有類文件修改,如果你在一個安全管理器下運行,反射會尊重安全管理器。原來的問題沒有解決它,所以我也沒有。 –

1

當你想要使用元數據時,通常反射很有用;一個例子是像休眠這樣的orm框架,它使用了很多反射功能,等等......

相關問題