概述
反射是框架设计的灵魂。Java反射说的是在运行状态中,对于任何一个类,我们都能够知道这个类有哪些方法和属性。对于任何一个对象,我们都能够对它的方法和属性进行调用。我们把这种动态获取对象信息和调用对象方法的功能称之为反射机制。(讲的啥呀,不知道…下面看图说话)
反射的好处: ①可以在程序运行过程中,操作这些对象;②可以解耦,提高程序的可拓展性。
下面来分析一下java代码在计算机运行的三个阶段:
源代码阶段 我们在编写好java代码之后,这个时候还不能运行,得先通过javac进行编译,如果代码没有什么问题,会生成一个.class的字节码文件。字节码文件中有着三个重要的东西:成员变量、构造方法、成员方法。这就是java代码在计算机的第一个阶段,成为源代码阶段。这个时候Java代码并没有进内存,还是在硬盘上。
Class类对象阶段 .class字节码文件通过类加载器ClassLoader加载进内存,这就是java代码在内存的第二个阶段。在内存里边,有一个Class类用来描述进入内存的.class字节码文件的共同特征和行为,比如都有成员变量(封装为Filed对象)、构造方法(封装为Constructor对象)、成员方法(封装为Method对象)。
运行时阶段 通过类对象的这些特征行为,我们就可以真正创建对象(new Person())。
通过上面对java代码在计算机的阶段,可以得到一个结论:将类的各个组成部分封装为其他对象,这就是反射机制。
应用
一、基本反射技术
获取Class对象的三种方式
①.getClass方式:getClass()方法是在Object类中定义,多用于对象获取字节码的方式
String s="HelloWorld";
Class c = s.getClass();
System.out.println(c1.getName());
②.class方式:通过类名的属性class获取,多用于参数的传递
Class c=Person.class;
//获取类的名称
System.out.println(c.getName());
③Class.forName方式:将字节码文件加载进内存,返回Class对象,多用于配置文件,将类名定义在配置文件中。读取文件,加载类。
String s = "HelloWorld";
Class c = null;
//因为传入的字符串可能不合法,所以需要处理异常
try {
c = Class.forName(s);
//可以获得父类
c.getSuperclass();
System.out.println(c.getName());
} catch (ClassNotFoundException e) {}
Type属性
得到基本类型的类型
Class c1 = Boolean.TYPE;
Class c2 = Byte.TYPE;
Class c3 = Float.TYPE;
Class c4 = Double.TYPE;
二 获取类的成员变量
①Field[] getFields():获取所有public修饰的成员变量
②Field getField(String s):获取指定名称的public修饰的成员变量
③Field[] getDeclaredFields():获取所有成员变量,不考虑修饰符
三 获取构造方法
①Constructor<?>[] getConstructors():获得该类的所有公有构造方法
②Constructor getConstructor(类<?>… parameterTypes):获得该类中与参数类型匹配的公有构造方法
③Constructor getDeclaredConstructor(类<?>… parameterTypes):获得该类中与参数类型匹配的构造方法
④Constructor<?>[] getDeclaredConstrutors():获得该类所有构造方法
四 获取成员方法
①Method[] getMethods():获得该类所有公有的方法
②Method getMethod(String s,类<?>…paremeterTypes):获得该类某个公有的方法
③Method[] getDeclaredMethods():获得该类所有方法
④Method getDeclaredMethod(String s,类<?>…parameterTypes):获得该类某个方法