作为一个Java新人,我谈谈自己对Java反射机制的认识,给其他的Java新人以启蒙作用。通俗的讲,java的反射就是,当一个类被加载以后,Java虚拟机就会自动产生一个Class对象。通过这个Class对象我们就能获得加载到虚拟机当中这个Class对象对应的方法、成员以及构造方法的声明和定义等信息。
那么,如何获取这个Class对象呢?通常有以下几种做法:
1.如果已经得到一个类的实例,可以使用如下方式来得到Class对象:
Class c = 对象名.getClass();
例:Student s = new Student();
Class c = s.getClass();
Class c2 = s.getSuperclass();
2.如果在编译期仅知道类的名字(如仅知道有一个Student类被编译了),可以使用如下方法(这也是一种反射,
用于获取类的一个class对象):
Class c = Student.class;
3.如果类名在编译期不知道,但是在运行期可以获得,可以使用下面的方法:
Class c = Class.forName(str);//这里的str是类的全路径
下面我们来看看,怎样获取一个类的所有成员变量:
Student.java:
public class Student {
/** 学号 */
public static String id = "20140210102";
/** 姓名 */
public String name = "张三";
/** 年龄 */
public int address = 18;
/** 电话 */
protected long phone = 18765342152L;
/** 是否党员 */
private boolean ispp = false;
public Student() {
}
}
Test.java
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
public class Test {
public static void main(String[] args) throws Exception {
Student s = new Student();
/*
* 下面这句代码仅通过反射获取到运行时消息头部的已声明字段,不包括方法
* ①.这里如果用getFields(),返回的是声明为public的属性的成员,包括父类中定义的成员
* ②.用getDeclaredFields(),返回的是指定类定义的所有定义的属性,不包括父类的。
*/
Field[] fs = Student.class.getDeclaredFields();
for (int i = 0; i < fs.length; i++) {
Field f = fs[i];
f.setAccessible(true);// 如果没有这句代码将无法访问类的私有成员变量,程序编译时会抛出异常
/*
* 下面这句代码表示:
*
* 以整数形式返回由此 Field对象表示的字段的Java语言修饰符(即public,private,protected
* ,default,static,final等修饰符的整数形式)
*/
int memberMod = f.getModifiers();
// 将整数形式转化为具体的类型名称并打印出来
System.out.print(Modifier.toString(memberMod) + " ");
// 获取成员变量的类型(基本数据类型or对象,如果是对象,就会显示出该对象的派生类名称)
String memberType = f.getGenericType().toString().intern();
System.out.print(memberType + " ");
// 获取成员变量的名称
String memberName = f.getName();
System.out.print(memberName + " ");
// 获取具体的值并打印
System.out.print(f.get(s) + "\n");
}
}
}运行结果:
public static class java.lang.String id 20140210102
public class java.lang.String name 张三
public int address 18
protected long phone 18765342152
private boolean ispp false
希望能通过这个例子对java新手认识反射有一定的帮助,下一篇,我们来看看如何通过反射来获取成员方法!