- 浏览: 361309 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (176)
- struts2 (4)
- javascript (9)
- database (11)
- hibernate (11)
- java (36)
- CSS (1)
- wap (8)
- html (5)
- spring (3)
- 操作系统 (9)
- xml (0)
- eclipse/myeclipse (6)
- freemarker (2)
- jsp+servlet (4)
- fckeditor (1)
- Linux (12)
- tomcat (4)
- SNMP (2)
- Loadrunner (1)
- php (0)
- 版本控制 (1)
- android (3)
- pki (7)
- jquery (4)
- webservice (4)
- ipad (1)
- 开发工具 (1)
- jslt (1)
- 连接池 (6)
- javaApi (1)
- 学习笔记 (6)
- eclipse (2)
最新评论
-
宋建勇:
nice
keytool详解 -
1122334455aabb:
java int,byte、char之间的相互转化,更多内容参 ...
java中byte 与16进制字符相互转换 -
01jiangwei01:
CA[i >>> 18 & 0x3f ...
使用JAVA数字证书做数字签名认证 -
sjp524617477:
good
keytool详解 -
whlngn:
输出结果我只想取汉字,而不要后面的数字,应该如何实现,求回答
配置paoding analysis
因一时兴起看了一些有关 Java 反射( Reflection )的东西。以下要说明的问题是如何直接对某个特定类的私有属性( private field )不使用其暴露的 set 方法而是直接进行设值操作,或调用类的私有方法( private method )。
首先要说明的是,这在 java 里是允许这么做的。虽然这样直接访问私有属性或调用私有方法,会破坏了 OO 的一大基本原则:封装,但 Java 里是千真万确的提供了这么做的基础的。一些 Open source framework 的“豪华”功能也是依赖于此的。
此前在网上看到不少兄弟提出过这样的问题,有人略带讽刺的回复说这样做是不可以的。在这里不才给出一个简单的示例来说明如何完成的这个被看成 Mission Imposable 的。
首先我们建立一个测试用的类( TargetClass ):
package org.rossalee.test;
public class TargetClass {
public String name ;
private String age ;
public TargetClass() {
super ();
}
public void showName() {
System. out .println( name );
}
private void showAge() {
System. out .println( age );
}
}
这个目标类里有一个 public 权限 String 类型 “ name ” 属性和一个 private 权限 String 类型的“ age ”属性,以及一个 public 方法“ showName() ”和 private 方法“ showAge() ”。
一般来说我们是可以直接操作该类的 name 属性或调用 showName() 方法的。这都是很正常。但如果想要对 age 属性进行设值的话,那就只能依靠 TargeClass 提供一个修饰为 public 的 setAge(String age) 的设值方法,才能进行设值。但我们上面这个类里并没有提供,所以那这个 age 属性基本上是没有办法进行再设值的了。同样,我们也不可以调 TargetClass 类的 shwoAge() 方法。因为他也是 private 的。
但我们使用 Java Core API 提供的 Reflect 就可以完成这个功能。
以下是实现对私有属性进行操作的基本步骤:
<!---->一、 <!---->使用 Class 对象提供的 static 方法 forName() 方法,将类进行加载,成为 Java 里一种特殊的对象——类对象。
<!---->二、 <!---->使用 Class 对象提供的方法 getDeclaredFields() ,此方法 返回 Field
对象的一个数组,这些对象反映此 Class
对象所表示的类或接口所声明的所有字段。即有公共的也有私有的。
<!---->三、 <!---->调用对于要进行操作的 field 对象的 setAccessible() 。参数传入“ true ”。此方法从 java.lang.reflect.AccessibleObject 对象中继承而来。执行该方法后,就可以对 age 属性进行操作了。但设值是要有特定的方法来实现的。另外,还有一点要说明的是,此时加载的类对象是没有实例化的,所以最终我们要进行设值的并不是这个类对象,而 TargetClass 类型的对象。这个对象你可以自己 new 出来,也可以通过调用类对象的 newInstance() 方法实例出来。在这里我们暂定这个 new 出来的 TargetClass 对象为 tc ,即:
TargetClass tc=new TargetClass() 。
<!---->四、 <!---->这时我们要用 Field 对象提供的 set(Object obj, Object value) 方法进行设置。这个方法有两个参数: obj 就传入我们在一步 new 出来的 tc 。 Value 就传入 age 所属类型的值,这里的 age 是 String 类型,这里传一个 String 进来就可以了。
对于私有方法的调用也基本相同,但只是最后使用的是 Method 对象的 invoke(Object obj, Object... args) 方法。 Obj 一样也是 tc , args 则是 showAge() 方法的参数,这里是无参的,所以传一个 null 进去就可以了。
实现代码如下:
package org.rossalee;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import org.rossalee.test.TargetClass;
public class TestMain {
public static void main(String[] args) {
Class clazz = null ;
try {
clazz = Class.forName ( "org.rossalee.test.TargetClass" );
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
Field[] f = clazz.getDeclaredFields();
for ( int i = 0; i < f. length ; i++) {
System. out .println( "Field " + i + " : " + f[i].getName());
}
Method[] m = clazz.getDeclaredMethods();
for ( int i = 0; i < m. length ; i++) {
System. out .println( "Method " + i + " : " + m[i].getName());
}
TargetClass tc = null ;
try {
tc = (TargetClass) clazz.newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
f[1].setAccessible( true );
try {
f[1].set(tc, "kenshin" );
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
m[1].setAccessible( true );
try {
m[1].invoke(tc, null );
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
发表评论
-
常用排序算法小记
2012-06-29 07:59 965转自:http://easense2009.iteye.com ... -
抽象类与接口
2012-06-07 13:47 809java中只可以继承一个类却可以继承多个接口。一个抽象 ... -
Java编程中“为了性能”尽量要做到的一些地方
2012-05-18 09:36 655最近的机器内存又爆满了,除了新增机器内存外,还应该好好revi ... -
Runtime.getRuntime().exec(...)使用方法
2011-01-25 11:06 3317如果想要了解更多的信息,参阅代码里面给的链接 下面是这个正确的 ... -
使用poi一步一步建立报表 (excel操作)
2011-01-08 20:21 1627... -
Apache POI HSSF读写Excel总结
2011-01-08 18:03 1369Apache POI HSSF和XSSF读写EXCEL总结 H ... -
JNLP介绍
2010-12-05 15:04 1906原文地址:http://blog.csdn.net/yq7 ... -
如何编写高效率java代码
2010-09-08 12:38 1517如何编写高效率Java 规则1 用时间频度来确定异常情况 ... -
深入理解Java加载类的机制
2010-09-07 22:32 1157这里从三个方面讲述java classloader ... -
Java 动态加载类
2010-09-07 22:29 2313Java 动态加载类 收 ... -
简单例子演示如何进行类的热加载(Hot Deployment)
2010-09-07 22:13 1733简单例子演示如何进行 ... -
ResourceBundle与Properties两个类的区别
2010-08-26 14:09 1633这两个类都是读取properties格式的文件的,而Prope ... -
log4j多文件配置
2010-08-26 10:07 1530log4j.rootCategory=INFO, CONSOL ... -
java获取properties 配置文件
2010-08-26 09:21 1786根据网上的例子总结了一下。 其中cache.p ... -
Class.forName与new 得区别
2010-08-13 15:45 1097Class.forName(xxx.xx.xx) 返回一个类 ... -
HttpURLConnection简单用法
2010-08-04 15:00 1625HttpURLConnection为javaAPI提 ... -
java中byte 与16进制字符相互转换
2010-07-27 13:53 7480Java中byte用二进制表示占用8位,而我们知道16进制的每 ... -
使用Axis在Tomcat下发布Webservice操作指南
2010-06-21 12:58 2498最近在工作过程中总是需要向其它项目组提供Webservice ... -
jdk安装
2010-06-12 21:41 14771.1 获取 JDK Java 的 ... -
System.load 和 System.loadLibrary
2010-06-12 08:37 1475System.load 和 System.loadLibrar ...
相关推荐
在Java编程语言中,反射(Reflection)是一种...通过阅读和分析这个文件,你可以更深入地理解如何利用反射来获取和设置私有属性的值。在实际学习中,你可以尝试运行这个程序,观察其输出,以便更好地掌握反射的用法。
尽管可以利用反射访问私有成员,但这应被视为一种特殊情况下的权宜之计,而不是常规编程实践。在单元测试中,适度使用反射可以帮助验证私有方法的行为,但也要注意保持测试的独立性和稳定性。在设计和实现代码时,应...
在本篇文章中,我们将深入探讨如何利用C#中的反射机制来访问类中的私有变量或方法。通过一个具体的示例代码,我们将详细了解反射的基本概念、使用场景以及如何具体操作。 ### 一、C#反射机制简介 #### 1.1 什么是...
本文主要讲解了在遇到需要操作Java对象的参数或返回值时,如何利用Frida这一动态代码插桩工具来进行反射调用,包括调用对象的方法和获取对象的字段。Frida是一个强大的动态代码插桩工具,它可以注入到几乎所有的进程...
4. 设置访问权限:如果要访问私有字段,需要先调用`Field`对象的`setAccessible(true)`方法,以绕过访问控制检查。 5. 赋值:最后,使用`Field`对象的`set()`方法,传入目标对象和要赋的值,即可完成属性赋值。例如...
然而,对于类的私有成员(包括私有方法和私有属性),由于其封装性,通常不易直接进行测试。但实际情况中,私有成员可能对类的行为产生关键影响,因此测试它们也是必要的。本文将介绍如何使用JUnit4结合Java的反射...
4. **测试工具**:JUnit等测试框架使用反射来调用私有方法或设置私有字段。 然而,反射也有其缺点,如性能损耗、安全风险(暴露私有成员)和代码可读性降低。因此,除非必要,一般不建议滥用反射。 博文链接提供的...
在Java编程语言中,反射(Reflection)是一种强大的工具,它允许程序在运行时检查和操作对象的内部结构,包括类的属性、方法以及构造器。...通过上述步骤,你可以有效地利用反射获取和操作类的父类属性和方法。
一旦我们有了`Class`对象,我们就可以利用反射来创建对象,调用方法和访问属性。例如,我们可以使用`newInstance()`方法创建一个新对象,但前提是没有参数的构造函数: ```java Person person = (Person) person...
通过反射,我们可以访问私有属性,甚至可以调用无公开接口的方法。 ```java public class ReflectionCopy { public static void copyProperties(Object source, Object target) throws Exception { Class<?> ...
本文将详细介绍如何利用Java反射机制来访问和操作父类的所有属性和方法。 #### 二、Java反射基础 在深入讨论如何操作父类之前,我们先简要回顾一下Java反射的基本概念: - **Class**: 每个类都有一个与之对应的`...
在给定的场景中,我们利用反射机制实现了动态调用计算器的加法和减法函数,并修改了学生对象的私有数据成员。下面将详细讲解这些知识点。 首先,让我们关注`Calculator`类中的加法和减法函数。假设`Calculator`类有...
在.NET框架中,反射是一种强大的工具,它允许程序在运行时检查自身并执行各种操作,如创建对象、访问属性和方法、以及调用未知类型的成员。在这个实例中,我们将探讨如何使用反射来调用DLL(动态链接库)中的方法。 ...
在Java编程语言中,"反射拷贝属性"是一种利用反射机制来复制对象属性的技术。反射是Java提供的一种强大工具,允许程序在运行时检查和操作类、接口、字段和方法等对象。通过反射,我们可以动态地获取类的信息并操作类...
Java反射机制是Java语言提供的一种强大功能,它允许我们在运行时检查类、接口、字段...在上述示例中,我们展示了如何利用反射来实现计算器的动态调用和修改私有学生对象的属性,这些都展示了反射机制的灵活性和实用性。
总的来说,尽管私有属性和方法在设计上是不可直接访问的,但是通过反射API,我们可以进行必要的测试,以确保这些隐藏的实现细节也能正常工作。然而,这种方法应当谨慎使用,因为过度依赖反射可能会影响代码的清晰性...
这个“VB.NET 反射类属性名称”主题聚焦于如何利用反射来获取或设置类中特定属性的值,尤其是当我们只知道属性的名称,而没有直接的引用时。 反射的基本原理是通过System.Reflection命名空间中的类来实现的。在这个...
Java动态调用方法是Java反射机制的一个重要应用,它允许我们在程序运行时,根据需要动态地获取类的信息并调用其方法。这种能力为代码的灵活性和可扩展性...在实际使用中,应结合具体需求权衡利弊,合理利用反射功能。
标题“Java反射机制修改私有成员变量的实现_Reflection”着重讲述了如何利用反射来修改私有成员变量的值。在Java中,私有成员变量通常被视为封装的一部分,不被外部类直接访问。然而,通过反射,我们可以绕过这种...
注意,对于私有方法,需要设置`Method`的`accessible`属性为`true`。 以下是一个简单的示例代码片段,展示了如何通过反射调用assets下JAR文件中的方法: ```java // 获取AssetManager AssetManager assetManager =...