2011-11-16 70 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框架,它使用了很多反射功能,等等......

相关问题