什么是反射?
当程序运行时,允许改变程序结构或变量类型,这种语言称为动态语言。我们认为 Java 并不是动态语言,但是它却有一个非常突出的动态相关机制,俗称:反射。
我们为什么需要反射?
IT 行业里这么说,没有反射也就没有框架,现有的框架都是以反射为基础。在实际项目开发中,用的最多的是框架,填的最多的是类,反射这一概念就是将框架和类揉在一起的调和剂。所以,反射才是接触项目开发的敲门砖!
1、 Class 对象
而在 java 语言中,static 修饰的东西不是对象,但是它属于类。普通的数据类型不是对象,例如:int a = 5; 它不是面向对象,但是它有其包装类 Integer 或者分装类来弥补了它。除了以上两种不是面向对象,其余的包括类也有它的面向对象,类是 java.lang.Class 的实例化对象(注意 Class 是大写)。也就是说:
Class D7{ }
当我创建了D7 类,那么类A本身就是一个对象,谁的对象? java.lang.Class 的实例对象。
声明一个类:
class D7 {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
获取 Class 对象一般有三种方式:
//1、Class 类
D7 d7 = new D7();
//方法一
Class c1 = D7.class;
//方法二
Class c2 = d7.getClass();
//方法三
Class c3 = null;
try {
c3 = Class.forName("keven.com.review.D7");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
System.out.println(c1 == c2);
System.out.println(c1 == c3);
第一种表达方式同时也告诉了我们任何一个类都有一个隐含的静态成员变量 class;
第二种表达方式在已知了该类的对象的情况下通过 getClass 方法获取;
第三种则通过类的全称获得。
上述代码的结尾输出为两个 true,我们思考下为什么呢?
因为不论 c1 or c2 or c3 都代表了F类的类类型,也就是说一个类只可能是 Class 类的一个实例对象。
2、 方法的反射
//2、方法的反射
Class c = D7.class;
Method[] methods = c.getMethods();
for (int i = 0; i < methods.length; i++) {
String name = methods[i].getName();
Class<?> returnType = methods[i].getReturnType();
System.out.println("methodName--" + name);
System.out.println("methodReturnType--" + returnType);
}
3、 成员变量的反射
//3、成员变量的反射
Field[] fields = c.getFields();//获取的所有的 public 的成员变量的信息
Field[] declaredFields = c.getDeclaredFields();//获取所有自己声明的成员变量的信息
for (Field fs : fields) {
System.out.println("Fields--"+fs.getType().getName());
System.out.println("Fields--"+fs.getName());
}
for (Field fs : declaredFields) {
System.out.println("declaredFields--"+fs.getType().getName());
System.out.println("declaredFields--"+fs.getName());
}
4、 构造函数的反射
Class c = obj.getClass();
/*
* 首先构造函数也是对象,是java.lang.Constructor类的对象
* 也就是java.lang. Constructor中封装了构造函数的信息
* 和前面说到的一样,它也有两个方法:
* getConstructors()方法获取所有的public的构造函数
* getDeclaredConstructors()方法得到所有的自己声明的构造函数
*/
//Constructor[] cs = c.getConstructors();
Constructor[] cs = c.getDeclaredConstructors();
for (Constructor constructor : cs) {
//我们知道构造方法是没有返回值类型的,但是我们可以:
System.out.print(constructor.getName()+"(");
//获取构造函数的参数列表》》得到的是参数列表的类类型
Class[] paramTypes = constructor.getParameterTypes();
for (Class class1 : paramTypes) {
System.out.print(class1.getName()+",");
}
System.out.println(")");
}
5、通过 newInstance() 方法生成类实例
Class class = D7.class;
D7 d7 = class.newInstance();