博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java反射 私有字段和方法
阅读量:7041 次
发布时间:2019-06-28

本文共 4509 字,大约阅读时间需要 15 分钟。

尽管普遍认为通过Java Reflection可以访问其他类的私有字段和方法。 这并不困难。 这在单元测试中可以非常方便。 本文将告诉你如何。

###访问私有字段 要访问私有字段,您需要调用Class.getDeclaredField(String name)或Class.getDeclaredFields()方法。 方法Class.getField(String name)和Class.getFields()方法只返回公共字段,所以它们将不起作用。 下面是一个带有私有字段的类的简单例子,下面是通过Java反射访问该字段的代码:

public class PrivateObject {  private String privateString = null;  public PrivateObject(String privateString) {    this.privateString = privateString;  }}PrivateObject privateObject = new PrivateObject("The Private Value");Field privateStringField = PrivateObject.class.            getDeclaredField("privateString");//关闭对此特定字段实例的访问检查privateStringField.setAccessible(true);String fieldValue = (String) privateStringField.get(privateObject);System.out.println("fieldValue = " + fieldValue);复制代码

此代码示例将打印出“fieldValue = The Private Value”文本,该文本是在代码示例开始时创建的PrivateObject实例的private字段privateString的值。

注意使用PrivateObject.class.getDeclaredField(“privateString”)方法。 这是这个方法调用返回私人字段。 此方法只返回在该特定类中声明的字段,而不是在任何超类中声明的字段。

注意粗线也是。 通过调用Field.setAccessible(true),可以关闭对此特定字段实例的访问检查,仅用于反射。 现在,即使调用者不是这些范围的一部分,即使它是私有的,受保护的或包的范围,也可以访问它。 您仍然无法使用正常代码访问该字段。 编译器不会允许它。 ###访问私有方法 要访问私有方法,您将需要调用Class.getDeclaredMethod(String name,Class [] parameterTypes)或Class.getDeclaredMethods()方法。 方法Class.getMethod(String name,Class [] parameterTypes)和Class.getMethods()方法只返回公共方法,所以它们将不起作用。 下面是一个带私有方法的类的简单示例,下面是通过Java反射访问该方法的代码:

public class PrivateObject {  private String privateString = null;  public PrivateObject(String privateString) {    this.privateString = privateString;  }  private String getPrivateString(){    return this.privateString;  }}复制代码
PrivateObject privateObject = new PrivateObject("The Private Value");Method privateStringMethod = PrivateObject.class.        getDeclaredMethod("getPrivateString", null);privateStringMethod.setAccessible(true);String returnValue = (String)        privateStringMethod.invoke(privateObject, null);System.out.println("returnValue = " + returnValue);复制代码

此代码示例将在代码示例的开头处创建的PrivateObject实例上调用时,打印出文本“returnValue = The Private Value”,这是getPrivateString()方法返回的值。 注意使用PrivateObject.class.getDeclaredMethod(“privateString”)方法。 正是这个方法调用返回私有方法。 通过调用Method.setAccessible(true),可以关闭此特定Method实例的访问检查,仅用于反射。 现在,即使调用者不是这些范围的一部分,即使它是私有的,受保护的或包的范围,也可以访问它。 您仍然无法使用普通代码访问该方法。 编译器不会允许它。

###实战

package com.reflection.detail;import java.lang.reflect.Field;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;/** * Created by Fant.J. * 2018/2/7 15:28 */public class Reflection_Private {    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {        //获取对象        Class aClass = People.class;        Field  privateField = aClass.getDeclaredField("privateString");        //设置允许jvm编译通过。(jvm 默认不允许访问 私有类型的东西)        privateField.setAccessible(true);        //获取私有字段的值        People people = new People();        Object privateStringResult = privateField.get(people);        System.out.println(privateStringResult);        //获取私有方法            //获取setPrivateString方法        Method privateMethod = aClass.getDeclaredMethod("setPrivateString", String.class);            //获取getPrivateString方法        Method privateMethod1 = aClass.getDeclaredMethod("getPrivateString", null);            //jvm编译通过允许        privateMethod.setAccessible(true);            //反射对象和参数 给setPrivateString方法        privateMethod.invoke(people,"Fant.J is so cool");            //反射对象和参数 给getPrivateString方法        Object obj = privateMethod1.invoke(people,null);        System.out.println(obj);    }}复制代码
package com.reflection.detail;/** * Created by Fant.J. * 2018/2/7 14:37 */public class People {    private Integer id;    private String name;    //field 字段    public String someField = "FantJ";    private String privateString = "shuai";    public People(Integer id, String name) {        this.id = id;        this.name = name;    }    public String getSomeField() {        return someField;    }    public void setSomeField(String someField) {        this.someField = someField;    }    public String getPrivateString() {        return privateString;    }    public void setPrivateString(String privateString) {        this.privateString = privateString;    }    public People(){}    public Integer getId() {        return id;    }    public void setId(Integer id) {        this.id = id;    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }}复制代码
shuaiFant.J is so cool复制代码

项目代码:

转载地址:http://dlaal.baihongyu.com/

你可能感兴趣的文章
获取的一个网页木马分析
查看>>
基于PIX525的NAT配置
查看>>
grub的安装
查看>>
3、Jenkins升级和迁移
查看>>
Centos7系列(一)Centos7新特性、安装与基本命令
查看>>
如何配置标准和分布式交换机
查看>>
Linux内核的ftrace调试接口
查看>>
应用SAAS结构技术的开源药店管理系统-源代码结构说明
查看>>
tushiba笔记本的显卡驱动
查看>>
zabbix 监控web-url是否正常
查看>>
C++学习路线图(重整理)
查看>>
清理系统更新的垃圾
查看>>
用户系列之三:用户登录及访问资源的过程之访问令牌篇
查看>>
Microsoft Search Server 2008部署及配置
查看>>
Android线程处理简述
查看>>
240多个jQuery插件
查看>>
$ORACLE_HOME路径更改导致的listener启动失败
查看>>
24.Silverlight多线程技术BackgroundWorker的应用,更新ProgressBar控件
查看>>
构建高性能ASP.NET站点 第五章—性能调优综述(后篇)
查看>>
Linux自动备份脚本
查看>>