反射(类的加载和加载时机)
类的加载概述:
* 当程序要使用某个类时,如果该类还未被加载到内存中,则系统会通过加载,连接,初始化三步来实现对这个类进行初始化。
加载:
* 就是指将class文件读入内存,并为之创建一个Class对象,任何类被使用时系统都会建立一个Class对象。
连接:
* 验证:是否有正确的内部结构,并和其他类协调一致。
* 准备:负责为类的静态成员分配内存,并设置默认初始化值。
* 解析:将类的二进制数据中的符号引用替换为直接引用。
初始化
加载时机:
* 创建类的实例。
* 访问类的静态变量或者为静态变量赋值。
* 调用类的静态方法。
* 使用反射方式来强制创建某个类或接口对应的java.lang.Class对象
* 初始化某个类的子类
* 直接使用某个Java.exe命令来运行某个主类。
反射(类加载器的概述和分类)
类加载器的概述:
* 负责将 . class文件加载到内存中,并为之生成对应的Class对象。
反射(反射概述)
反射概述:
* Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;
* 对于任意一个对象,都能够调用它的任意一个方法和属性。
* 这种动态获取的信息以及动态调用对象的方法的功能称为Java语言的反射机制。
三种方式:
* Object了哦的getClass( )方法,判断两个对象是否时同一个字节码文件。
* 静态属性class,锁对象。
* Class类中静态方法forName(),读取配置文件
反射(通过反射获取带参构造方法并使用)
Constructor:
* Class类的newInstance()方法时使用该类无参的构造函数创建对象,如果一个类没有无参的构造函数,就不能这样创建了。可以调用 Class类的getConstructor(String.class, int.class)方法获取一个指定的构造函数然后在调用Constructor类的newInstance()方法创建对象。
public static void main(String[] args) throws Exception { Class clazz = Class.forName("com.bean.Person"); Person p1 = (Person) clazz.newInstance(); // 通过无参构造创建对象 p1.setName("lisi"); // 设置姓名 p1.setAge(17); // 设置年龄 System.out.println(p1); Constructor c = clazz.getConstructor(String.class, int.class); // 获取有参构造 Person person = (Person) c.newInstance("张三", 15); // 通过有参构造创建对象 System.out.println(person.getName() + person.getAge()); }
反射(通过反射获取成员变量并使用)
Field:
* Class.getField(String)方法可以获取类中的指定字段(可见的)。如果时私有的可以用getDeclaredField("name")方法获取,通过set( obj,value)方法可以设置指定对象该字段的值。如果是私有的需要先调用setAccessible(true)设置权限访问。
public static void main(String[] args) throws Exception { Class clazz = Class.forName("com.bean.Person"); Constructor c = clazz.getConstructor(String.class, int.class); // 获取有参构造 Person person = (Person) c.newInstance("张三", 15); // 通过有参构造创建对象 // Field ff=clazz.getField("name"); //获取姓名字段(字段必须不是private) // ff.set(person, "李四"); //修改姓名的值 Field f = clazz.getDeclaredField("name"); // 暴力反射获取字段 f.setAccessible(true); // 去除私有权限 f.set(person, "王五"); System.out.println(person); }
public static void main(String[] args) throws Exception { Class clazz = Class.forName("com.bean.Person"); Constructor c = clazz.getConstructor(String.class, int.class); // 获取有参构造 Person c1=new Person(); //对象 Method m=clazz.getMethod("eat"); //获取无参的方法 m.invoke(c1); Method m1=clazz.getMethod("eat",int.class); //获取有参的方法 m1.invoke(c1,10); }
public static void main(String[] args) throws Exception { ArrayList<Integer> list = new ArrayList<>(); list.add(111); list.add(222); Class clazz = Class.forName("java.util.ArrayList"); //获取字节码对象 Method m = clazz.getMethod("add", Object.class); //获取add方法 m.invoke(list, "abc"); System.out.println(list); }