Java反射整理总结
1.
java源码--编译-->java字节码--类的加载-->JVM
当字节码文件加载到内存之后,JVM会为它创建一个Class对象(字节码文件的对象)
2.类的加载时机
类的字节码文件什么时候会被加载???
a.创建类的实例。
b.访问类的静态变量
c.调用类的静态方法
d.使用反射方式来强制加载某个类
e.使用到了该类的子类,也会导致该类被加载
f.直接使用java.exe命令运行某个测试类(含有main方法的类)
总而言之:
类的字节码文件什么时候会被加载,当我们用到该类或者该类的子类时!
3.类加载器的作用和分类
类加载器(ClassLoader),将字节码文件加载到JVM的内存中 类加载器的分类: 根类加载器(引导类加载器): 用于加载系统类库(比如:%JAVA_HOME%\bin下的这些类) 扩展类加载器: 用于加载扩展类库(比如:库<JAVA_HOME>\lib\ext目录下的类) 应用类加载器: 用于加载我们自定义类的加载器.
4.双亲委派机制
双亲委派机制的作用
1、防止重复加载同一个.class。通过委托去向上面问一问,加载过了,就不用再加载一遍。保证数据安全。 2、保证核心.class不能被篡改。通过委托方式,不会去篡改核心.clas,即使篡改也不会去加载,即使加载也不会是同一个.class对象了。不同的加载器加载同一个.class也不是同一个Class对象。这样保证了Class执行安全。
双亲委派模型工作工程: 1.当Application ClassLoader 收到一个类加载请求时,他首先不会自己去尝试加载这个类,而是将这个请求委派给父类加载器Extension ClassLoader去完成。 2.当Extension ClassLoader收到一个类加载请求时,他首先也不会自己去尝试加载这个类,而是将请求委派给父类加载器Bootstrap ClassLoader去完成。 3.如果Bootstrap ClassLoader加载失败(在<JAVA_HOME>\lib中未找到所需类),就会让Extension ClassLoader尝试加载。 4.如果Extension ClassLoader也加载失败,就会使用Application ClassLoader加载。 5.如果Application ClassLoader也加载失败,就会使用CustomClassLoader(用户自定义类加载器)去尝试加载。
6.如果均加载失败,就会抛出ClassNotFoundException异常。
//1 Class clas = Dog.class; System.out.println(clas); //2 Dog dog = new Dog(); System.out.println(dog.getClass()); //3 Class aClass = Class.forName("day26_classLoader.Dog"); System.out.println(aClass);
反射中万物皆对象: 一个成员方法 --> Method类型对象 一个成员变量 --> Field类型对象 一个构造方法 --> Constructor类型对象 2个常见的单词: newInstance: 创建对象 invoke: 执行方法/调用方法 反射的语法: 创建对象: 正常语法: 类名 对象名 = new 构造方法(参数); 反射语法: 类名 对象名 = 构造方法对象.newInstance(); 调用方法: 正常语法: 对象名.方法(参数); 反射语法: 方法对象.invoke(对象名,参数);
setAccessible(true)想要调用私有构造或方法必须设置此参数
获取反射类的构造
构造方法:
public Constructor<T> getConstructor(Class<?>... parameterTypes) 获取public修饰, 指定参数类型所对应的构造方法 public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes) 获取指定参数类型所对应的构造方法(包含私有的) public Constructor<?>[] getConstructors() 获取所有的public 修饰的构造方法 public Constructor<?>[] getDeclaredConstructors() 获取所有的构造方法(包含私有的)
根据构造不同的参数区分获取
Class<Dog> dogClass = Dog.class; Constructor<Dog> constructor = dogClass.getConstructor(); Constructor<Dog> constructorName = dogClass.getConstructor(String.class); Constructor<Dog> constructor1 = dogClass.getDeclaredConstructor(String.class,int.class);
//如果构造方法是非public,那么我们需要调用getDeclaredConstructor获取 Constructor con = cc.getDeclaredConstructor(String.class);
//如果是私有构造,那么必须先设置暴力访问权限 con.setAccessible(true); Object con = con4.newInstance("旺财");
获取反射类的成员
返回一个成员变量
public Field getField(String name) 获取指定的 public修饰的变量public Field getDeclaredField(String name) 获取指定的任意变量 返回多个成员变量 public Field[] getFields() 获取所有public 修饰的变量 public Field[] getDeclaredFields() 获取所有的 变量 (包含私有) public void set(Object obj, Object value)在指定对象obj中,将此 Field 对象表示的成员变量设置为指定的新值
public Object get(Object obj)返回指定对象obj中,此 Field 对象表示的成员变量的值
//成员变量 Class<Dog> dogClass = Dog.class; Field field = dogClass.getField("towname"); System.out.println(field.get(dogClass.newInstance())); Field name = dogClass.getDeclaredField("name"); //必须暴力获取私有 name.setAccessible(true); System.out.println(name.get(dogClass.newInstance()));
//获取所有成员变量 Field[] fields = dogClass.getFields(); System.out.println(Arrays.toString(fields));
获取成员方法: 返回获取一个方法: public Method getMethod(String name, Class<?>... parameterTypes)获取public 修饰的方法 public Method getDeclaredMethod(String name, Class<?>... parameterTypes)获取任意的方法,包含私有的 参数1: name 要查找的方法名称; 参数2: parameterTypes 该方法的参数类型 返回获取多个方法: public Method[] getMethods() 获取本类与父类中所有public 修饰的方法 public Method[] getDeclaredMethods() 获取本类中所有的方法(包含私有的)
Class<Dog> dogClass = Dog.class; Method method = dogClass.getMethod("drink"); Method eat = dogClass.getMethod("eat", String.class); Method eat1 = dogClass.getMethod("eat"); Dog dog = dogClass.newInstance(); //调用invoke method.invoke(dog); eat.invoke(dog,"😀"); eat1.invoke(dog); //获取私有 Method declaredMethod = dogClass.getDeclaredMethod("testD", String.class); declaredMethod.setAccessible(true); declaredMethod.invoke(dog,"xiao");
成员变量: 返回一个成员变量 public Field getField(String name) 获取指定的 public修饰的变量 Field ageField = c.getField("age"); public Field getDeclaredField(String name) 获取指定的任意变量 Field addressField = c.getDeclaredField("address"); 返回多个成员变量 public Field[] getFields() 获取所有public 修饰的变量 Field[] fields = c.getFields(); //遍历 public Field[] getDeclaredFields() 获取所有的 变量 (包含私有) Field[] fields = c.getDeclaredFields(); for (Field field : fields) { System.out.println(field); } public void set(Object obj, Object value) 在指定对象obj中,将此 Field 对象表示的成员变量设置为指定的新值 nameField.set(obj, 23) public Object get(Object obj) 返回指定对象obj中,此 Field 对象表示的成员变量的值 nameField.get(obj) nameField,nameField都是通过getField()获得的对象

浙公网安备 33010602011771号