JavaSE-初识反射
8.1 类加载器
ClassLoader: 是负责加载类的对象
Java运行时具有以下内置类加载器
- Bootstrap classloader: 它是虚拟机的内置类加载器,通常表示为null,并且没有父null
- Platform class loader: 平台类加载器可以看到所有平台类,平台类包括由平台类加载器或其祖先定义的JavaSE平台API其实现类和JDK特定的运行时类
- System class loader:它也被称为应用程序类加载器,与平台类加载器不同。系统类加载器通常用于定义应用程序类路径模块路径和JDK特定工具上的类
- 类加载器的继承关系: System的父加载器为Platform,而Platform的父加载器为Bootstrap
ClassLoader中的两个方法
static ClassLoadergetSystemClassLoader0: 返回用于委派的系统类加载器
ClassLoadergetParent0: 返回父类加载器进行委派
ClassLoader c = ClassLoader.getSystemClassLoader(); System.out.println(c); ClassLoader c2 = c.getParent(); System.out.println(c2); ClassLoader c3 = c2.getParent(); System.out.println(c3);
8.2 获取Class 类的对象
这里我们提供三种方式获取Class类型的对象
使用类的class属性来获取该类对应的Class对象。举例: Studentclass将会返回Student类对应的Class对象
调用对象的getClass0方法,返回该对象所属类对应的Class对象
该方法是Obiect类中的方法,所有的Java对象都可以调用该方法
使用Class类中的静态方法forName(StringclassName),该方法需要传入字符串参数,该字符串参数的值是某个类的全路径,也就是完整包名的路径
Class c1 = Student.class; System.out.println(c1); Class<Student> c2 = Student.class; System.out.println(c1 == c2); System.out.println("--------"); Student s = new Student(); Class<? extends Student> c3 = s.getClass(); System.out.println(c1 == c3); System.out.println("--------"); Class<?> c4 = Class.forName("lm_7_14.Student"); System.out.println(c1 == c4);
8.3 反射获取构造方法并使用
Class类中用于获取构造方法的方法
- Constructor< ? >]getConstructors(): 返回所有公共构造方法对象的数组
- Constructor< ? >getDeclaredConstructors(): 返回所有构造方法对象的数组
- Constructor< T >getConstructor(Class< ? >...parameterTypes): 返回单个公共构造方法对象
- Constructor< T > getDeclaredConstructorClass< ? >...parameterTypes): 返回单个构造方法对象
Constructor类中用于创建对象的方法
Tnewlnstance(Obiect...initargs): 根据指定的构造方法创建对象
// 获取Class对象 Class<?> c = Class.forName("lm_7_14.Student"); // 返回一个包含Constructor对象的数组,Constructor对象反映了由该Class对象表示的类的所有公共构造函数 //Constructor<?>[] cons = c.getConstructors(); // 返回反应由该Class对象表示的类声明的所有构造函数的Constructor对象的数组 Constructor<?>[] cons = c.getDeclaredConstructors(); for (Constructor<?> con : cons) { System.out.println(con); } System.out.println("--------"); // 返回一个Constructor对象,Constructor对象反映了由该Class对象表示的类的指定的公共构造函数 // 返回一个Constructor对象,由对象反映由此Class对象表示的类或接口的指定构造函数 // 参数:你要获取的构造方法的参数个数和数据类型对应的字节码文件对象 Constructor<?> con = c.getConstructor(); Object obj = con.newInstance(); System.out.println(obj);
注意:
1. 基本数据类型也可以通过.class得到对应的Class类型
2. 当需要调用类的私有构造方法时,可以通过该方法暴力反射
public void setAccessible(boolean flag):值为true,取消访问检查
8.4反射获取成员变量并使用
Class类中用于获取成员变量的方法
- FieldgetFields0: 返回所有公共成员变量对象的数组
- FieldlgetDeclaredFields0: 返回所有成员变量对象的数组
- FieldgetField(String name): 返回单个公共成员变量对象
- FieldgetDeclaredField(String name): 返回单个成员变量对象
Field类中用于给成员变量赋值的方法
void set(Obiect obj, Obiect value): 给obj对象的成员变量赋值为value
Class<?> c = Class.forName("lm_7_14.Student"); // Field[] fields = c.getFields(); Field[] fields = c.getDeclaredFields(); for (Field field : fields) { System.out.println(field); } System.out.println("-------------"); Field addField = c.getField("add"); // 获取无参构造方法创建对象 Constructor<?> con = c.getConstructor(); Object obj = con.newInstance(); addField.set(obj,"西安"); System.out.println(obj);
8.5 反射获取成员方法并使用
Class类中用于获取成员方法的方法
- Method[] getMethods(): 返回所有公共成员方法对象的数组,包括继承的
- Method[] getDeclaredMethods(): 返回所有成员方法对象的数组,不包括继承的
- Method getMethod(Stringname,Class < ? >... parameterTypes): 返回单个公共成员方法对象
- Method getDeclaredMethod(String name,Class< ? >... parameterTypes): 返回单个成员方法对象
Method类中用于调用成员方法的方法
Objectinvoke(Object obj, Object...args): 调用obj对象的成员方法,参数是args,返回值是Object类型
Class<?> c = Class.forName("lm_7_14.Student"); // Method[] methods = c.getMethods(); Method[] methods = c.getDeclaredMethods(); for (Method method : methods) { System.out.println(method); } System.out.println("-------------"); Method m = c.getMethod("method1"); Object obj = c.getConstructor().newInstance(); m.invoke(obj);