反射
反射 Class类 获取文件字节码对象的三种方法 public class Demo01 { public static void main(String[] args) throws ClassNotFoundException { //获取文件字节码对象的三种方法 //Class类:描述文件对象的类 //1.通过对象获取 Person p=new Person(); Class c=p.getClass(); System.out.println(c); //2.通过类名获取 Class c1=Person.class; System.out.println(c1); System.out.println(c==c1);//证明了字节码文件对象在堆里就一个 System.out.println(c.equals(c1)); //3.通过Class类中的静态方法forName(完整的包名+类名)获取 Class c2=Class.forName("com.oracle.demo02.Person"); System.out.println(c2); } }
通过反射获取构造方法并使用 import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; //Class类:描述文件对象 //Constructor类:描述构造方法的类 //Method类:描述方法的类 //Filed类:描述变量的类 public class Demo02 { public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { //获取Person的字节码文件对象 Class c=Class.forName("com.oracle.demo02.Person");//静态代码块 //获取该类中所有公共的构造方法 数组 Constructor[] cons=c.getConstructors(); for(Constructor con:cons){ System.out.println(con); } //获取该类中的公共空参构造 Constructor con1=c.getConstructor(); //使用构造方法对象去创建Person对象 Object obj=con1.newInstance();//这是个多态 System.out.println(obj); Person p=(Person)obj;//强转调用自己独有的方法 p.eat(); //获取该类中的公共有参构造并使用 Constructor con2=c.getConstructor(String.class,int.class); Object obj2=con2.newInstance("飒",1); System.out.println(obj2); //反射获取空参构造方法并运行的快速方式 //前提:1.被反射的类必须有空参构造方法 //2.该方法必须是public修饰 Object obj3=c.newInstance();//是Class类中的方法 不再是构造方法里的了 System.out.println(obj3); } }
import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; public class Demo03 { public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchFieldException { method1(); //method2(); //method3(); } public static void method1() throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException{ Class c=Class.forName("com.oracle.demo02.Person"); //反射获得Person类中所有的构造方法 /*Constructor[] cons=c.getDeclaredConstructors(); for(Constructor con:cons){ System.out.println(con); }*/ //反射获得私有的有参构造 Constructor con=c.getDeclaredConstructor(String.class); //暴力反射 破坏了程序的封装性,安全性 可以下面方法暴力反射 但不推荐 //调用父类的方法避免java语言的访问检查 con.setAccessible(true); Object obj=con.newInstance("李四"); System.out.println(obj); }
通过反射获取成员变量并使用 public static void method2() throws NoSuchFieldException, SecurityException, InstantiationException, IllegalAccessException{ //反射获取成员变量并改值 Class c=Person.class; Field[] fileds=c.getDeclaredFields(); for(Field f:fileds){ System.out.println(f); } //获取Person类中的公共成员变量并改值 //快速创建一个Person对象 Object obj=c.newInstance(); Field field=c.getField("name"); field.set(obj, "张三"); System.out.println(obj); }
通过反射获取成员方法并使用 public static void method3() throws InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException{ //反射成员方法,并调用 Class c=Person.class; //快速创建一个Person对象 Object obj=c.newInstance(); //获取所有的方法 /*Method[] methods=c.getDeclaredMethods(); for(Method m:methods){ System.out.println(m); }*/ //获取公共有参构造并调用 Method method=c.getMethod("sleep",String.class); method.invoke(obj,"李四"); } }
反射练习 泛型擦除 import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayList; //泛型擦除 不推荐 了解 public class Demo04 { public static void main(String[] args) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { ArrayList<Integer> arr=new ArrayList<Integer>(); arr.add(1); //获取字节码文件对象 Class c=arr.getClass(); Method method=c.getMethod("add",Object.class); method.invoke(arr,"你好"); System.out.println(arr);//[1, 你好] } } 反射配置文件 public class Person { public void eat(){ System.out.println("人"); } } public class Student { public void study(){ System.out.println("学生学习"); } } public class Worker { public void work(){ System.out.println("工人"); } } #ClassName=com.oracle.demo03.Person #MethodName=eat #修改这一部分就OK了 ClassName=com.oracle.demo03.Worker MethodName=work import java.io.FileReader; import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Properties; public class Demo01 { //1.准备配置文件,Properties 键值对方式存储 public static void main(String[] args) throws IOException, ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { //2.IO流去读取配置文件中的键值对 Reader FileReader fr=new FileReader("config.properties"); //3.将文件中的键值对存储到集合中的Properties中 Properties pro=new Properties(); pro.load(fr); fr.close(); //4.从集合中获取类名和方法名 String className=pro.getProperty("ClassName"); String methodName=pro.getProperty("MethodName"); //5.反射获取指定类的class文件对象 Class c=Class.forName(className); //快速创建指定类对象 Object obj=c.newInstance(); //获取指定的方法 Method method=c.getMethod(methodName); //6.运行指定的方法 method.invoke(obj);//工人 } }