这篇文章主要介绍的是 Java 反射,包含反射的基本知识,对反射原理不了解的可以瞄一眼。
1.Class 类的使用
1.1 任何一个类都是 Class 类的实例对象
注意大小写!我们平时写的类都是普通的 class 类,而普通的类其实都是 Class 类的实例。举个例子,比如在正常情况下我们获取一个类的实例的方式为:
1 | Fruit banana = new Fruit(); |
那么就可以理解为:banana 是 Fruit 类的实例对象,而 Fruit 类是 Class 类的实例对象。
1.2 获取Class类的三种方式
第一种方式:
1 | Class c1 = Fruit.class; |
第二种方式:
1 | Class c2 = banana.getClass(); |
第三种方式:
1 | Class c3 = null; |
一个类只可能是 Class 类的一个实例对象,因此 c1 == c2、c2 == c3 都为 true。
通过 Class 类来创建某个类的实例的方式为:(对于 Class.forName() 这种方式,它会把字符串所代表的类 load 到内存,但不会创建类的实例,没有实例的话程序无法运行)
1 | try { |
1.3 Class 动态加载类
首先我们要明白静态加载和动态加载的区别。
静态加载:编译时加载类
动态加载:运行时加载类
辅助性的功能尽量使用动态加载,例如QQ的在线升级,在原有的代码不需要重新编译的情况下就能增加新功能。
静态加载 Demo:
1 | class StaticLoad |
1 | interface Fruit |
1 | class Apple implements Fruit |
用 new 创建对象是静态加载,编译时就会加载所有可能会用到的类,因为没有 Banana 类,所以上面的例子即使在用不到 Banana 类的情况下,编译时也会报错。
动态加载 Demo:
1 | class DynamicLoad |
1 | $ java DynamicLoad Apple(用反射后传什么类就运行什么类) |
以后别人在添加 Banana 类时,实现 Fruit 接口然后单独编译即可,不需要对以前的代码重新编译。
2.反射中常用的方法
1 | Class ca = obj.getClass(); |
3.通过反射调用具体方法
1 | public class MethodDemo1 |
有时我们可能会看到有些方法的参数中带有三个点,这表示该参数的个数不固定,我们在调用这个方法传参的时候,有多少个参数就传多少个参数。
4.通过 Class 和 Method 认识泛型的本质
1 | public class MethodDemo4 |
(完)