java反射机制:
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
要想解剖一个类,必须先要获取到该类的字节码文件对象。而解剖使用的就是Class类中的方法.所以先要获取到每一个字节码文件对应的Class类型的对象。
测试类:
package io.renren.modules.base; import lombok.Data; @Data public class ReflectionDemo { public String name; private String address; private int age; public ReflectionDemo(){ System.out.println("空参构造方法"); } private ReflectionDemo(String name){ this.name = name; } public ReflectionDemo(String name,int age, String address){ this.name = name; this.age = age; this.address = address; } public ReflectionDemo(String name,int age){ this.age = age; this.name = name; }
//公有方法 public void eat(String food){ System.out.println("吃—"+food); }
//私有方法 private void save(Double money,Integer age){ System.out.println("【"+this.name+"】存了【"+money+"】钱"+",今年:"+age+"岁"); } }
开始测试:
package io.renren.modules.base; import org.junit.Test; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.net.URL; /** * java类要经过编译—>运行两个阶段,编译器把.java文件编译成.class文件, * 而运行时期,则需要把class文件读进内存,过程分为:加载到内存、连接解析、初始化 * 加载:把class文件读进内存,然后再创建一个class对象 * 连接:协调类的内部, 将类的二进制数据中的符号引用替换为直接引用 * 初始化 * 1. 创建类的实例 * 2. 类的静态变量,或者为静态变量赋值 * 3. 类的静态方法 * 4. 使用反射方式来强制创建某个类或接口对应的java.lang.Class对象 * 5. 初始化某个类的子类 */ //@SpringBootTest public class reflectionTest { /** * 获取类的加载器 */ @Test public void test1(){ Class c = ReflectionDemo.class; System.out.println(c); Class<? extends Class> aClass = c.getClass(); System.out.println(aClass); ClassLoader classLoader = c.getClassLoader(); URL resource = classLoader.getResource(""); System.out.println(resource); } /** * 获取类的class对象,字节码对象 */ @Test public void test2(){ //第一种方法 ReflectionDemo demo = new ReflectionDemo(); Class<? extends ReflectionDemo> aClass = demo.getClass(); System.out.println(aClass); //第二种方法 Class c = ReflectionDemo.class; System.out.println(c); //第三种方法 try { Class cn = Class.forName("io.renren.modules.base.ReflectionDemo"); System.out.println(cn); } catch (ClassNotFoundException e) { e.printStackTrace(); } } /** * 获取构造方法、成员变量、成员方法 */ @Test public void test3() throws Exception{ //获取空参构造方法 Class c = ReflectionDemo.class; //获取所有public构造方法 Constructor[] constructors = c.getConstructors(); for (Constructor con: constructors){ System.out.println(con); } //获取所有的构造方法,包括私有、公共 Constructor[] constructors1 = c.getDeclaredConstructors(); for (Constructor con: constructors1){ System.out.println(con); } //获取某个公共的构造方法,参数类型要对应 Constructor constructor = c.getConstructor(String.class, Integer.class); ReflectionDemo object =(ReflectionDemo) constructor.newInstance("小明", 190); System.out.println(object); Constructor constructor1 = c.getConstructor(); System.out.println(constructor1); //获取某个构造方法,包括私有、公有 Constructor declaredConstructors = c.getDeclaredConstructor(String.class); Constructor declaredConstructors2 = c.getDeclaredConstructor(String.class, Integer.class); System.out.println(declaredConstructors+"====="+declaredConstructors2); //private,取消 Java 语言访问检查 declaredConstructors.setAccessible(true); ReflectionDemo object2 =(ReflectionDemo) declaredConstructors.newInstance("小明"); System.out.println(object2); //获取所有公有变量 Field[] fields = c.getFields(); for(Field f: fields){ System.out.println(f); } //获取所有变量 Field[] declaredFields = c.getDeclaredFields(); for(Field f: declaredFields){ System.out.println(f); } //获取公有变量 Field ageField = c.getField("name"); System.out.println(ageField); //获取所有公有方法 Method[] method = c.getMethods(); for(Method m: method){ System.out.println(m); } //获取公有方法 Method method1 = c.getMethod("eat", String.class); System.out.println(method1); //获取方法、包括私有、公有 Method method2 = c.getDeclaredMethod("save", Double.class); method2.setAccessible(true); System.out.println(method2); } /** * 获取成员变量 */ @Test public void test4() throws Exception{ Class c = ReflectionDemo.class; //获取到有参构造方法 Constructor con = c.getDeclaredConstructor(String.class); //赋值 con.setAccessible(true); Object object = con.newInstance("小明"); System.out.println(object); Field name = c.getField("name"); Object value1 = name.get(object); Field name2 = c.getDeclaredField("age"); name2.setAccessible(true); Object value2 = name2.get(object); //没赋值,为null Field name3 = c.getDeclaredField("address"); name3.setAccessible(true); Object value3 = name3.get(object); System.out.println(value1); System.out.println(value2); System.out.println(value3); } /** * 执行方法 */ @Test public void test5() throws Exception{ Class c = Class.forName("io.renren.modules.base.ReflectionDemo"); Constructor constructor = c.getDeclaredConstructor(String.class); constructor.setAccessible(true); Object object = constructor.newInstance("小明"); Method eatMethod = c.getMethod("eat", String.class); eatMethod.invoke(object, "菜果"); Method saveMethod = c.getDeclaredMethod("save", Double.class,Integer.class); saveMethod.setAccessible(true); //反射执行方法,object,实例对象,也就是执行哪个实例的方法,方法的参数 saveMethod.invoke(object,200000d,24); } }