JAVA中的反射机制对私有成员的访问
2009-02-11 10:40
309 查看
先讲下原理:
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
Java反射机制主要提供了以下功能:
在运行时判断任意一个对象所属的类;
在运行时构造任意一个类的对象;
在运行时判断任意一个类所具有的成员变量和方法;
在运行时调用任意一个对象的方法;
生成动态代理。
举例子说明如下:
首先我们建立一个测试用的类( 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);
}
}
注意其中的age 属性是私有的。
一般来说我们是可以直接操作该类的 name 属性或调用 showName() 方法的。这都是很正常。但如果想要对 age 属性进行设值的话,那就只能依靠 TargeClass提供一个修饰为 public 的 setAge(String age) 的设值方法,才能进行设值。但我们上面这个类里并没有提供,所以那这个 age 属性基本上是没有办法进行再设值的了。同样,我们也不可以调 TargetClass类的 shwoAge() 方法。因为他也是 private 的。
但我们使用 Java Core API 提供的 Reflect 就可以完成这个功能。
实现代码如下:
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) {
Classclazz = 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());
}
TargetClasstc = 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();
}
}
}
以下是实现对私有属性进行操作的基本步骤:
一、 使用 Class对象提供的 static 方法 forName() 方法,将类进行加载,成为 Java 里一种特殊的对象——类对象。
二、 使用 Class对象提供的方法 getDeclaredFields() ,此方法 返回
三、 调用对于要进行操作的 field 对象的 setAccessible() 。参数传入“ true ”。此方法从 java.lang.reflect.AccessibleObject 对象中继承而来。执行该方法后,就可以对 age 属性进行操作了。但设值是要有特定的方法来实现的。另外,还有一点要说明的是,此时加载的类对象是没有实例化的,所以最终我们要进行设值的并不是这个类对象,而 TargetClass类型的对象。这个对象你可以自己 new 出来,也可以通过调用类对象的 newInstance() 方法实例出来。在这里我们暂定这个 new 出来的 TargetClass对象为 tc ,即:
TargetClasstc=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 进去就可以了。
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
Java反射机制主要提供了以下功能:
在运行时判断任意一个对象所属的类;
在运行时构造任意一个类的对象;
在运行时判断任意一个类所具有的成员变量和方法;
在运行时调用任意一个对象的方法;
生成动态代理。
举例子说明如下:
首先我们建立一个测试用的类( 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);
}
}
注意其中的age 属性是私有的。
一般来说我们是可以直接操作该类的 name 属性或调用 showName() 方法的。这都是很正常。但如果想要对 age 属性进行设值的话,那就只能依靠 TargeClass提供一个修饰为 public 的 setAge(String age) 的设值方法,才能进行设值。但我们上面这个类里并没有提供,所以那这个 age 属性基本上是没有办法进行再设值的了。同样,我们也不可以调 TargetClass类的 shwoAge() 方法。因为他也是 private 的。
但我们使用 Java Core API 提供的 Reflect 就可以完成这个功能。
实现代码如下:
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) {
Classclazz = 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());
}
TargetClasstc = 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();
}
}
}
以下是实现对私有属性进行操作的基本步骤:
一、 使用 Class对象提供的 static 方法 forName() 方法,将类进行加载,成为 Java 里一种特殊的对象——类对象。
二、 使用 Class对象提供的方法 getDeclaredFields() ,此方法 返回
Field对象的一个数组,这些对象反映此
Class对象所表示的类或接口所声明的所有字段。即有公共的也有私有的。
三、 调用对于要进行操作的 field 对象的 setAccessible() 。参数传入“ true ”。此方法从 java.lang.reflect.AccessibleObject 对象中继承而来。执行该方法后,就可以对 age 属性进行操作了。但设值是要有特定的方法来实现的。另外,还有一点要说明的是,此时加载的类对象是没有实例化的,所以最终我们要进行设值的并不是这个类对象,而 TargetClass类型的对象。这个对象你可以自己 new 出来,也可以通过调用类对象的 newInstance() 方法实例出来。在这里我们暂定这个 new 出来的 TargetClass对象为 tc ,即:
TargetClasstc=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 进去就可以了。
相关文章推荐
- java中的反射机制——如何访问私有成员的私有方法
- JavaSE第六十四讲:使用反射机制调用对象的私有方法、访问对象的私有成员变量
- 使用类的反射机制来访问类的私有成员变量
- Java利用反射访问对象的私有成员
- java 反射机制 之 getDeclaredField 获取私有保护字段, 再setAccessible(true)取消对权限的检查 实现对私有的访问和赋值
- Java中的反射机制,利用反射访问私有
- 使用C#反射机制访问类的私有成员【转】
- Java通过反射访问私有成员变量和私有方法
- Java中的反射机制 利用反射访问私有
- java反射访问私有成员变量
- java利用反射访问类的私有成员
- Java中的反射机制(三) 利用反射访问私有
- java的反射可以绕过访问权限,访问到类的私有方法和成员
- java 反射机制 读取私有成员变量
- C# 反射机制(reflection)实现对私有成员的访问
- 通过java反射技术访问类中私有成员属性
- java中用反射访问私有方法和私有成员
- Java中的反射机制(四) 利用反射访问私有
- 【转载】JAVA利用反射机制访问private成员和方法
- Java反射访问私有成员