简体   繁体   English

通过在Java中使用反射来访问和修改私有类成员

[英]Accessing and modifying private class members through the use of reflection in Java

The following program is accessing and modifying a private field named privateKey declared within the class SimpleKeyPair . 以下程序正在访问和修改在类SimpleKeyPair声明的名为privateKey的私有字段。 Let's have a look at it. 让我们来看看它。

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

In the code above, the private field privateKey declared within the class SimpleKeyPair is being accessed and displayed on the console through the following statements. 在上面的代码中,私人领域的privateKey在类中声明SimpleKeyPair被访问,并通过下面的语句显示在控制台上。

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

and that field is being modified and the new value of that field is being displayed through the following statements. 并且正在修改该字段,并通过以下语句显示该字段的新值。

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

The actual output of the program would be as under. 该程序的实际输出如下。

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

Means that the use of reflection in Java allows a direct access to private resources. 意味着在Java中使用反射可以直接访问私有资源。 If it is so then, declaring a member as private itself in Java is not safe though one of the aims of declaring class members as private is to hide them from outside the world. 如果是这样,那么在Java中将成员声明为私有本身并不安全,尽管将类成员声明为私有的目的之一就是将它们隐藏在外界之外。 What is the actual use of reflection in Java? Java中反射的实际用途是什么?

You are correct that reflection can allow access to private (and package and protected) scoped members of a class. 您是正确的,反射可以允许访问类的私有(以及打包和受保护的)作用域成员。 However, if you read the JavaDocs, you will find that all of the methods for fetching and invoking these accessors perform a SecurityManager check before performing the requested operation. 但是,如果您阅读JavaDocs,则会发现所有用于获取和调用这些访问器的方法在执行请求的操作之前都执行SecurityManager检查。 So, in an environment with a SecurityManger, the operations will fail with SecurityExceptions being thrown. 因此,在具有SecurityManger的环境中,操作将因抛出SecurityExceptions而失败。

What is the use of reflection? 反射有什么用? Introspection, the ability to make dynamic calls/resolutions, tooling, etc. 内省,进行动态调用/解决方案,工具等的能力。

Do you mean what is the actual use of private ? 您是说private的实际用途是什么? To declare intent, and disallow casual abuse of private members. 宣布意图,并禁止随意滥用私人成员。 Heh. h

In generally reflection is useful when you want work with metadata; 通常,当您要使用元数据时,反射很有用; an example are the orm framework like hibernate that use a lot of reflection capabilities and so on... 一个例子是像休眠这样的orm框架,它使用很多反射功能,等等。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM