Java反射
1、什么是Java反射 参考:https://xz.aliyun.com/t/9117
Java提供了一套反射API,该API由Class类与java.lang.reflect类库组成。
该类库包含了Field、Method、Constructor等类。
对成员变量,成员方法和构造方法的信息进行的编程操作可以理解为反射机制。
2、为什么要用到反射 参考:https://xz.aliyun.com/t/9117
其实从官方定义中就能找到其存在的价值,在运行时获得程序或程序集中每一个类型的成员和成员的信息,从而动态的创建、修改、调用、获取其属性,而不需要事先知道运行的对象是谁。划重点:在运行时而不是编译时。(不改变原有代码逻辑,自行运行的时候动态创建和编译即可)
3、反射机制应用 开发应用场景:
Spring框架的IOC基于反射创建对象和设置依赖属性。
SpringMVC的请求调用对应方法,也是通过反射。
JDBC的Class#forName(String className)方法,也是使用反射。
安全应用场景:
构造利用链,触发命令执行
反序列化中的利用链构造
动态获取或执行任意类中的属性或方法
动态代理的底层原理是反射技术
rmi反序列化也涉及到反射操作
#Java-反射-Class对象类获取普通用户我们可以采用以下方法创建实例: 1 Person test = new Person();
而我们在创建class类的实例对象却不能使用上述方法,运行会抛出错误
1 Class test = new Class();
跟进Class类的源码进行查看,发现其构造器是私有的,所以只有JVM能够创建Class对象。
因为Class类是private私有属性,我们也无法通过创建对象的方式来获取class对象,那么我们怎样才能够获取到class对象呢?一般我们获取class对象就有以下几种方法,我们来逐一看看。
1 2 3 4 5 6 7 8 9 10 //1、根据类名:类名.class Class userClass =User.class; //2、根据对象:对象.getClass() User user =new User(); Class aClass = user.getClass(); //3、根据全限定类名:Class.forName("全路径类名") Class aClass1 =Class.forName("com.example.reflectdemo.User"); //4、通过类加载器获得Class对象://ClassLoader.getSystemClassLoader().loadClass("全路径类名"); ClassLoader clsload=ClassLoader.getSystemClassLoader(); Class aClass2 = clsload.loadClass("com.example.reflectdemo.User");
实现代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 public class ReflectTemo { public static void main(String[] args) throws ClassNotFoundException { //1、类的.class属性 Class c1 = ReflectTemo.class; System.out.println(c1.getName()); //2、实例化对象的getClass()方法 ReflectTemo demo = new ReflectTemo(); Class c2 = demo.getClass(); System.out.println(c2.getName()); //3、Class.forName(String className): 动态加载类 Class c3 = Class.forName("org.example.ReflectTemo"); System.out.println(c3.getName()); //4、通过类加载器获得Class对象://ClassLoader.getSystemClassLoader().loadClass("全路径类名"); ClassLoader c4=ClassLoader.getSystemClassLoader(); Class aClass2 = c4.loadClass("org.example.ReflectTemo"); System.out.println(aClass2.getName()); } }
#Java-反射-Field成员变量类获取 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 //Class aClass = Class.forName("com.example.reflectdemo.User"); //获取公共成员变量对象 // Field[] fields=aClass.getFields(); // for(Field f:fields){ // System.out.println(f); // } //获取所有成员变量对象 // Field[] fields=aClass.getDeclaredFields(); // for(Field f:fields){ // System.out.println(f); // } //获取公共,私有单个成员变量对象 // Field field=aClass.getField("age"); // Field field=aClass.getDeclaredField("gender"); // System.out.println(field); //城边变量值获取和赋值 // User u = new User(); // Field field=aClass.getField("age"); // field.set(u,30); // Object a=field.get(u); // System.out.println(a);
实现代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 public class ReflectTemo { public String name; public String profession; protected int age; private String number; char sex; public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException { Class aClass = Class.forName("org.example.ReflectTemo"); // 获取公共成员变量对象 Field[] fields = aClass.getFields(); for (Field f : fields) { System.out.println(f); } System.out.println("-------分割线---------"); // 获取所有成员变量对象 Field[] fields1 = aClass.getDeclaredFields(); for (Field f : fields1) { System.out.println(f); } System.out.println("-------分割线---------"); // 获取公共,私有单个成员变量对象 Field field = aClass.getField("name"); Field field1 = aClass.getDeclaredField("number"); System.out.println(field.getName()); System.out.println(field1.getName()); System.out.println("-------分割线---------"); // 获取指定成员变量 Field field2 = aClass.getDeclaredField("age"); System.out.println(field2); } }
Java-反射-Method成员方法类获取 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 //Class aClass = Class.forName("com.example.reflectdemo.User"); //返回所有公共成员方法对象的数组,包括继承的 // Method[] methods = aClass.getMethods(); // for (Method me:methods){ // System.out.println(me); // } //返回所有成员方法对象的数组,不包括继承的 // Method[] methods = aClass.getDeclaredMethods(); // for (Method me:methods){ // System.out.println(me); // } //返回单个公共成员方法对象 // Method methods = aClass.getMethod("getName"); // System.out.println(methods); // Method methods = aClass.getMethod("setName", String.class); // System.out.println(methods); //返回单个成员方法对象 // Method methods = aClass.getDeclaredMethod("UserInfo", String.class, int.class, String.class); // System.out.println(methods); //运行方法invoke // Method methods = aClass.getDeclaredMethod("UserInfo", String.class, int.class, String.class); // User u = new User(); // //私有需要开启临时 // methods.setAccessible(true); // methods.invoke(u,"calmsec",18,"man");
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 public class ReflectTemo { public void study(String s) { System.out.println("学习中..." + s); } protected void run() { System.out.println("跑步中..."); } void eat() { System.out.println("吃饭中..."); } private String sleep(int age) { System.out.println("睡眠中..." + age); return "sleep"; } public static void main(String[] args) { try { Class c = Class.forName("org.example.ReflectTemo"); // 创建Class对象 Method[] methods1 = c.getDeclaredMethods(); // 获取所有该类中的所有方法 Method[] methods2 = c.getMethods(); // 获取所有的public方法,包括类自身声明的public方法,父类中的public方法、实现的接口方法 for (Method m:methods1) { System.out.println(m); } System.out.println("-------分割线---------"); for (Method m:methods2) { System.out.println(m); } System.out.println("-------分割线---------"); Method methods3 = c.getMethod("study", String.class); // 获取公有方法 System.out.println(methods3); System.out.println("-------分割线---------"); Method method4 = c.getDeclaredMethod("sleep", int.class); // 获取私有方法 System.out.println(method4); } catch (Exception e) { e.printStackTrace(); } } }
#Java-反射-Constructor构造方法类获取 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 //Class aClass = Class.forName("com.example.reflectdemo.User"); //返回所有公共构造方法对象的数组 // Constructor[] constructors = aClass.getConstructors(); // for(Constructor con:constructors){ // System.out.println(con); // } //返回所有构造方法对象的数组 // Constructor[] constructors = aClass.getDeclaredConstructors(); // for(Constructor con:constructors){ // System.out.println(con); // } //返回单个公共构造方法对象 // Constructor con1=aClass.getConstructor(); // Constructor con1=aClass.getConstructor(String.class); // System.out.println(con1); //返回单个构造方法对象 // Constructor con2=aClass.getDeclaredConstructor(int.class); //Constructor con2=aClass.getDeclaredConstructor(String.class,int.class, String.class); // System.out .println(con2); // Constructor con2=aClass.getDeclaredConstructor(int.class); // con2.setAccessible(true); // User uu=(User) con2.newInstance("calmsec",30,"man"); // System.out.println(uu);
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 public class ReflectTemo { public ReflectTemo() { System.out.println("无参构造函数"); } public ReflectTemo(String name) { System.out.println("有参构造函数" + name); } private ReflectTemo(boolean n) { System.out.println("私有构造函数"); } public static void main(String[] args) { try { Class c1 = Class.forName("org.example.ReflectTemo"); Constructor[] constructors1 = c1.getDeclaredConstructors(); Constructor[] constructors2 = c1.getConstructors(); for (Constructor c : constructors1) { System.out.println(c); } System.out.println("-------分割线---------"); for (Constructor c : constructors2) { System.out.println(c); } System.out.println("-------分割线---------"); Constructor constructors3 = c1.getConstructor(String.class); System.out.println(constructors3); System.out.println("-------分割线---------"); Constructor constructors4 = c1.getDeclaredConstructor(boolean.class); System.out.println(constructors4); } catch (Exception e) { e.printStackTrace(); } } }