【译】7. Java反射——私有字段和私有方法
原文地址:http://tutorials.jenkov.com/java-reflection/private-fields-and-methods.html
===========================================================================================
尽管普遍的观点是不能直接访问私有字段和私有方法的,实际上通过Java反射是可以访问其他类的私有字段和私有方法的。它甚至不是那么困难。在单元测试期间很容易使用。本文将介绍你怎么做。
注:这个只会作用在运行独立的Java应用程序时,如写单元测试和常规应用。如果你尝试在Java Applet内使用它,你需要处理好SecurityManager。但是,因为这不是你经常要做的事情,所以在本文中将不会涉及它。
下面是本文的主题列表:
- Accessing Private Fields (访问私有字段)
- Accessing Private Methods (访问私有方法)
===========================================================================================
- Accessing Private Fields
为了访问私有字段,你需要调用Class.getDeclaredField(String name)方法或者Class.getDeclaredFields()方法。Class.getField(String name)和Class.getFields()方法只会返回public的字段,所有它们不会工作。下面是一个简单的例子,通过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实例在代码示例最开始赋值给私有字段privateString的。
注意这里使用的方法PrivateObject.class.getDeclaredField("privateString")。是这个方法调用返回了私有字段的值。这个方法只会返回在给定类里声明的字段的值,而不是其他任何在超类里声明的字段的值。
注意字体加粗的一行。仅仅针对反射,通过调用Field.setAccessible(true)方法,关闭了对特定的Field实例的访问检查。现在你可以访问它,尽管它是private,或者protected,或者是package scope,即使调用者不在这个范围内。你仍然不能通过一般的代码去访问这些字段。编译器不允许这样干。
===========================================================================================
- Accessing Private Methods
为了访问私有方法,你需要调用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);
这段代码示例将会打印出文本“returnValue = The Private Value”,是在代码示例最开始创建的PrivateObject实例调用getPrivateString()方法时的返回值。
注意这里使用的方法PrivateObject.class.getDeclaredMethod("privateString")。是这个方法调用返回的私有方法。这个方法只会返回在给定的类里面声明的方法,而不是在任何超类里声明的方法。
注意字体加粗的一行。仅仅针对反射,通过调用Method.setAccessible(true)方法,关闭了对特定的Method实例的访问检查。现在你可以访问它了,尽管它是private,或者protected,或者package scope,即使调用者不在这个范围内。你仍然不能通过一般的代码访问这些方法。编译器不允许这样干。
========================================================================================
- 目录
这是一个本教程到目前为止涵盖的主题列表:
- Java反射——引言
- Java反射——Class对象
- Java反射——构造函数
- Java反射——字段
- Java反射——方法
- Java反射——Getter和Setter
- Java反射——私有字段和私有方法
- Java反射——注解
- Java反射——泛型
- Java反射——数组
- Java反射——动态代理
- Java反射——类的动态加载和重新加载
(敬请期待下一篇翻译)
【译】7. Java反射——私有字段和私有方法的更多相关文章
- java反射机制(访问私有字段和私有方法)
来自:http://tutorials.jenkov.com/java-reflection/private-fields-and-methods.html 尽管我们通常认为通过JAVA的反射机制来访 ...
- Java反射理解(五)-- 方法反射的基本操作
Java反射理解(五)-- 方法反射的基本操作 方法的反射 1. 如何获取某个方法 方法的名称和方法的参数列表才能唯一决定某个方法 2. 方法反射的操作 method.invoke(对象,参数列表) ...
- Java反射-修改字段值, 反射修改static final修饰的字段
反射修改字段 咱们从最简单的例子到难, 一步一步深入. 使用反射修改一个private修饰符的变量name 咱们回到主题, 先用反射来实现一个最基础的功能吧. 其中待获取的name如下: public ...
- Python类总结-字段,方法,属性区别及StaticMethod, Property,私有字段和私有属性
类包含下列 静态属性 动态属性 静态方法 动态方法 class Province: #静态字段--属于类,调用方法类.字段名 memo = "中国23个省之一" #动态字段--属于 ...
- java 反射给字段重新赋值
1.获取实体的所有字段,遍历 2.获取字段类型 3.调用字段的get方法,判断字段值是否为空 4.如果字段值为空,调用字段的set方法,为字段赋值 Field[] field = model.getC ...
- 深入分析Java反射(一)-核心类库和方法
前提 Java反射的API在JavaSE1.7的时候已经基本完善,但是本文编写的时候使用的是Oracle JDK11,因为JDK11对于sun包下的源码也上传了,可以直接通过IDE查看对应的源码和进行 ...
- Java反射机制调用对象的方法 —— 将一个对象的属性值赋值给另一个对象的属性
模拟一个场景: 众所周知,EasyExcel导出Excel文档是依赖于注解完成的,在实体类需要导出的属性上面加上注解,导出的时候会自动识别该属性. 假如我们现在需要导出用户的信息,又不想污染原本的实体 ...
- 有关java反射的几个小方法的作用和区别
1.Class类中 getXXX()和getDeclaredXXX()的作用和区别: 前者获取某个类的所有公共(public)的字段(or方法or构造函数),包括父类.后者获取所有的字段(or方法or ...
- java反射调用某个对象的方法
// 反射调用某个对象的方法 public Object invokeMethod(Object methodObject, String methodName, Object[] args) thr ...
随机推荐
- 安装VC++2015运行库时出现0x80240037错误
很多时候,当我们将开发好的软件部署到用户的机器上时总会出现各种意想不到的错误,最近在一台原版Windows7系统的电脑上安装VC++运行库的时候,莫名的出现安装失败,然后错误代码为:0x8024003 ...
- jQuery的each使用陷阱
注意:jQuery使用each()函数进行循环时发现return false不能阻止程序继续向下执行 原因如下: (1)开始还以为是jQuery的each()函数是异步执行的,所以导致出错,其实不是. ...
- 插件 DataTable 创建列表 render参数的详解与如何传递本行数据id
1.首先 导入DataTable 的插件 2.定义表结构: HTML: <table> <thead> <tr> <th>id</th> & ...
- 提示“Web打印服务CLodop未安装启动”的各种原因和解决方法
旧版提示:"CLodop云打印服务(localhost本地)未安装启动!"新版提示:"Web打印服务CLodop未安装启动,点击这里下载执行安装(若此前已安装过,可点这里 ...
- c++ 的绝对值函数
添加头文件 #include <cmath> 对于整数 abs(); 对于浮点数 fabs();
- python基础数据类型—int、bool、字符串的常用方法
1.int int为整型数据,主要用于计算和类型转化(将字符串转为数字) 常用方法 #bit_length()当用二进制表示数字时所用最少位数,如下十进制数12用二进制表示是1100(bin),所以# ...
- 第四十一天 socker server和 event
今日内容 1.基于TCP的socketserver 2.基于UDP的socketserver 3.event 一.TCP的socketserver #服务器 import socketserver f ...
- I - Tunnel Warfare HDU - 1540 线段树最大连续区间
题意 :一段区间 操作1 切断点 操作2 恢复最近切断的一个点 操作3 单点查询该点所在最大连续区间 思路: 主要是push_up : 设区间x 为母区间 x<<1 ,x< ...
- BZOJ1001 洛谷4001 [BJOI2006]狼抓兔子 题解
题目 这个题目有多种解法,这个题也是一个比较经典的题了,正是因为他的多样的做法,这个题主要难在建图和优化,因为这是一个网格图,所以spfa肯定过不去,所以用最短路解法的话,只能用dij,而网络流也是要 ...
- Marriage Match III HDU - 3277(二分权值 + 拆点 建边)
题意: 只不过是hdu3081多加了k种选择 想一下,最多能玩x轮,是不是就是每个女生能最多选x个男生 现在题中的每个女生比3081多了k中选择 那就把女生拆点 i i‘ i --> i ...