0 Java反射机制
反射(Reflection)是 Java 的高级特性之一,是框架实现的基础。
0.1 定义
Java 反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为 Java 语言的反射机制。
一般而言,当用户使用一个类的时候,应该获取这个类,而后通过这个类实例化对象,但是使用反射则可以相反的通过对象获取类中的信息。
通俗的讲反射就是可以在程序运行的时候动态装载类,查看类的信息,生成对象,或操作生成的对象。它允许运行中的 Java 程序获取自身的信息,自己能看到自己,就像照镜子一样。【源自gitChat】
1 Class类的使用
1.1 扫盲知识点
在Java的世界里,万事万物都是对象【PS: 类也是一个对象】。
坑01:java语言中,静态成员、普通数据类型不是对象
技巧01:普通的数据类型虽然不是对象,但是普通的数据类型都有对应的包装类来让其转化成一个对象
技巧02:静态的成员是属于类的而不是属于对象的,所以静态的成员不是对象
技巧03:所有的类都是java.lang.Class的实例对象【there is a class name Class:Class类的实例就是所有的实例对象所属的类】
1.2 Class类实例的创建
任何一个类都是Class类的实例对象,Class类的实例对象有三种表示方式;
类也是一个实例对象,是Class类的实例对象,这个对象我们称为该类的类类型;
例如:我们创建一个名为Foo的类,Foo类就是Class类的实例对象,假设Foo类对应的Class类的实例名为c1,那么我们就称c1是Foo类的类类型
总结:类类型就是Class类的一个实例,而且一个类只能有一个类类型,也就是所一个类只能和一个Class对应;虽然可以通过三种方式创建一个Class实例,但是针对一个类而言这三种方式创建得到的Class实例都是相等的,因为一个类的类类型只能和一个Class的实例对象。(即:一个类通过三种方式创建的类类型其实是一样的)
技巧01:不同的类对应的类类型都不一样,同理,不同的类对应的Class类实例都不一样
技巧02:同一个类只有一个类类型,同理,同一个类只和一个Class类实例对应;所以,同一个类通过不同方式创建的类类型都是一样的
1.2.1 利用class创建
任何一个类都默认拥有一个名为class的静态成员变量,该类可以利用class静态成员去创建该类的类实例。
例如:创建了一个名为Foo的类,执行 Foo.class 就会创建一个 Class 的实例,我们把得到的Class实例命名为c1,这个c1就是Foo类对应的类类型
1.2.2 利用实例对象创建
如果已经得到了某个类的实例,那么可以调用这个实例的成员方法getClass去创建该实例所属类的类类型
例如:创建了一个名为Foo的类,根据Foo创建了一个Foo的实例对象foo,我们可以利用foo去调用getClass来创建Class类的一个实例c2,这个c2就是foo所属类Foo的类类型
1.2.3 利用Class类创建
Class类有一个静态方法forName,Class类可以利用这个静态方法创建一个Class实例;forName方法的参数是一个类的全名
例如:创建了一个类Foo,该类的全名为 demo06_reflect.case01_class.Foo ,那么就可以利 Class.forName("demo06_reflect.case01_class.Foo")
去创建一个Class类的实例c3,这个c3就是Foo类的类类型
package demo06_reflect.case01_class; /** * @author 王杨帅 * @create 2018-08-03 21:43 * @desc Class的使用 **/ public class Demo01_Class { public static void main(String[] args) { // 创建Foo类的一个实例foo, Foo是foo的实例类型,foo是Foo的一个实例 Foo foo = new Foo(); // Class实例创建01:利用静态成员calss创建 Class c1 = Foo.class; // Class实例创建02:利用实例成员ngetClass创建 Class c2 = foo.getClass(); // 因为一个类只和一个Class实例对应,所以结果为true System.out.println(c1 == c2); // Class实例创建03:利用Class类的静态成员forName创建 try { Class c3 = Class.forName("demo06_reflect.case01_class.Foo"); System.out.println(c1 == c3); } catch (ClassNotFoundException e) { e.printStackTrace(); } } } class Foo { public String name = "warrio"; public void pirnt() { System.out.println("foo"); } }