1.引言
已经很久没有写过Java代码了,写了一年的的C++,今天看到C++的friend(友元)可以操作一个类的private属性,突然想到Java的反射,今天用Java写了一小段代码实验了一下,项目中比较实用。也是在以前做安卓的项目的时候老是听到师傅说反射,没怎么用过,终于尝试了一下。
2.代码片段
Java的反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法。对于任意一个对象,都能够调用它的任意一个方法和属性。这种动态获取的信息以及动态调用对象的方法的功能称为Java语言的反射机制。
下面来看看我的代码片段:
package cn.reflect.demo;
/**
* 描述:实验Java的反射机制(部分)
* 作者:某种意境丶
* */
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class Reflect {
public static void main(String[] args) {
/** 1. 通过反射来调用一个类的方法 */
Class<?> data = null;
try {
data = Class.forName("cn.reflect.demo.Data");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
try {
// 调用Data类的print方法
Method method = data.getMethod("print");
System.out.print("通过反射来调用一个类的方法:");
// invoke的洋文意思就是 调用
method.invoke(data.newInstance());
} catch (Exception e) {
e.printStackTrace();
}
/** 2. 查看类名 */
Data newData = new Data();
System.out.print("完整的包名+类名:");
System.out.println(newData.getClass().getName());
/** 3. 通过反射来获取一个类的private字段 */
Object obj = null;
try {
obj = data.newInstance();
Field field = data.getDeclaredField("cnName");
// 这里设置访问权限为true
field.setAccessible(true);
// 为字段设置新内容
//field.set(obj, "某种意境丶");
String privateField = (String) field.get(obj);
System.out.print("获得的Private字段的值是:");
System.out.println(privateField);
} catch (Exception e) {
e.printStackTrace();
}
}
}
查看打印:
在访问私有属性的时候,field.setAccessible(true)的设置是很关键的,它把权限设置为true,从而让对象能够操作那个类的私有字段,类似get/set操作。
public void setAccessible(boolean flag) throws SecurityException {
SecurityManager sm = System.getSecurityManager();
if (sm != null) sm.checkPermission(ACCESS_PERMISSION);
setAccessible0(this, flag);
}
这是setAccessible的Java源码,可以看到有一个SecurityManager类来管理这些权限,具体的可以自己再查看Java源码怎么实现,这对自己的code能力也是很有帮助的。
如果不知道怎么查看Java源码,可以参考这篇文章:http://blog.csdn.net/dinghqalex/article/details/43764607