Java 反射机制
1:Class 类
在面向对象的世界里,万事万物皆对象,我们平时在java中创建的类,也是对象,这些类都是Class类的对象。
例如我们创建一个Student类,那么 Studentstu=new Student();这时候,stu是类Student的对象,而Student这个类又是Class类的对象。但是我们不能直接实例化Class这个类,因为在java中只有jvm才能实例化Class类。任何一个类都是Class类的实例对象。
Classc1=Student.class;
Classc2=stu.getClass();
Classc3=null; c3=Class.forName(“stu”);
C1,c2,c3表示了Student类的类类型。-----万事万物皆对象,类也是对象,类是Class类的实例对象,这个对象我们称为该类的类类型。
2:动态加载类
我们平时的new对象,就是静态加载类,在编译时刻就要加载所有可能用到的类。 而动态加载类,就是在程序运行时,通过反射,动态获取类的信息,然后创建类的实例从而加载类。动态加载类可以让我们的程序更灵活,实现热插拔。
一般我们可以通过
Class c = Class.forName(“stu”); //stu代表的是类的全路径名称
c.newInstance();
来动态加载一个类。
3:动态获取类详细信息
A:获取成员函数
/**
* 打印类的信息,包括类的成员函数
* @param obj该对象所属类的信息
*/
public static void printClassMessage(Object obj){
//要获取类的信息,首先获取类的类类型
Class c= obj.getClass();//传递的是哪个子类的对象,c就是该子类的类类型。
//获取类的名称
System.out.println("类的名称是" + c.getName());
/**
* method类,方法对象
* 一个成员方法就是一个method对象
* getMethods方法获取的是所有public的函数,包括父类集成而来的。
* c.getDeclaredMethods()获取的是所有该类自己声明的方法,不问访问权限
*/
Method[] ms=c.getMethods();
for (int i = 0; i < ms.length; i++) {
//得到方法的返回值类型的类类型
Class returnType=ms[i].getReturnType();
System.out.print(returnType.getName()+"");
//得到方法的名称
System.out.print(ms[i].getName()+"(");
//获取参数类型-->得到的是参数列表的类型的类类型
Class[] paramTypes=ms[i].getParameterTypes();
for (Class class1 : paramTypes) {
System.out.print(class1.getName()+",");
}
System.out.print(")");
/**
* 成员变量也是对象
* Field类封装了关于成员变量的操作
* getFields()方法获取的是所有public的成员变量的信息
* c.getDeclaredFields(); 获取的是所有该类自己声明的成员变量的信息。
*/
/*Field[] fs=c.getFields();*/
printFieldMessage(c);
}
}
B:获取成员变量
/**
* 获取成员变量的信息
* @param obj
*/
public static void printFieldMessage(Object obj) {
Class c=obj.getClass();
Field[] fs=c.getDeclaredFields();
for(Field field:fs){
//得到成员变量类型的类类型
Class fieldType=field.getType();
String typeName=fieldType.getName();
//得到成员变量的名称
String fieldName=field.getName();
System.out.println(typeName+" "+fieldName);
}
}
C:获取构造函数
/**
* 打印对象构造函数的信息
* @param obj
*/
public static void printConMessage(Object obj){
Class c= obj.getClass();
/**
* 构造函数Constructor也是对象
* java.long.Constructor中封装了构造函数的信息
* getConstructor获取所有public的构造函数
* getDeclaredConstructors得到所有的构造函数(因为构造函数必须是自己声明的)
*/
//Constructor[]cs=c.getConstructors();
Constructor[] cs=c.getDeclaredConstructors();
for (Constructor constructor : cs) {
System.out.print(constructor.getName()+"(");
//获取构造函数的参数列表--》得到的是参数列表的类类型
Class [] paramType=constructor.getParameterTypes();
for (Class class1 : paramType) {
System.out.print(class1.getName()+",");
}
System.out.println(")");
}
}
Java的反射机制是java语言中特别重要的一环,个人理解相当于动态反编译,它允许程序员在程序的运行过程中动态的将类加载入程序中,通过java反射我们可以更加灵活的配置我们的程序,我们常用的spring ioc 等底层实现都是基于java反射机制,可以说java反射机制造就了java语言的灵活性。