咱们可能都用过 Spring AOP ,底层的实现原理是怎样的呢?
反射常用于编写工具,企业级开发要用到的 Mybatis、Spring 等框架,底层的实现都用到了反射。能用好反射,就能提高我们编码的核心能力。
反射机制
JAVA反射机制是在运行状态中,对于任意一个实体类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性。
作用:
在运行时判断任意一个对象所属的类
在运行时构造任意一个类的对象
在运行时判断任意一个类所具有的成员变量和方法
在运行时调用任意一个对象的成员变量和方法
生成动态代理
常用的类:
java.lang.Class:代表一个类
java.lang.reflect.Method:代表类的方法
java.lang.reflect.Field:代表类的成员变量
java.lang.reflect.Constructor:代表类的构造方法
Class 类
Class 类的实例表示正在运行的 Java 应用程序中的类和接口,Class 没有公共构造方法,Class 对象是在加载类时由 Java 虚拟机及通过调用类加载器中的 defineClass 方法自动构造的。
一个类在 JVM 中只会有一个 Class 实例
一个 Class 对象对应的是一个加载到 JVM 中的一个 .class 文件
每个类的实例都会记得自己是由哪个 Class 实例所生成
通过 Class 可以完整地得到一个类中的完整结构
获取 Class 对象
获取 Class 对象有4种方式,前三种比较常用。
首先创建一个类用于测试
package com.jikedaquan.reflection;public class User { private int id; private String username; private String password; public User() { } public User(int id, String username, String password) { super(); this.id = id; this.username = username; this.password = password; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public void show() { System.out.println("Hello"); } @Override public String toString() { return "User [id=" + id + ", username=" + username + ", password=" + password + "]"; } }
编写测试
package com.jikedaquan.reflection;public class GetClass { public static void main(String[] args) { //方法1 try { Class clz1=Class.forName("com.jikedaquan.reflection.User"); } catch (ClassNotFoundException e) { e.printStackTrace(); System.out.println("找不到指定类"); } //方法2 Class clz2=User.class; //方法3 User user=new User(); Class clz3=user.getClass(); //方法4 类的加载器 try { Class clz4=GetClass.class.getClassLoader().loadClass("com.jikedaquan.reflection.User"); } catch (ClassNotFoundException e) { e.printStackTrace(); System.out.println("找不到指定类"); } } }
方法1语法:
Class Class对象 = Class.forName(包名+类名);
方法2语法:
Class Class对象 = 类名.class;
方法3语法:
Class Class对象 = 对象.getClass();
getClass() 方法是从 Object 类中继承过来的
获取类的结构
Class 类常用方法
方法名称 | 说明 |
---|---|
Annotation[] getAnnotations() | 返回此元素上存在的所有注解 |
Constructor<T> getConstructor(Class<?>... parameterTypes) | 获取指定参数的构造函数 |
Constructor<?>[] getConstructors() | 返回包含的公有构造方法 |
Constructor<?>[] getDeclaredConstructors() | 返回所有构造方法 |
Field getDeclaredField(String name) | 返回一个 Field 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明字段 |
Method getDeclaredMethod(String name, Class<?>... parameterTypes) | 根据方法名和参数获取方法对象 |
API 中可以看到有两种获取结构的方式:getDeclaredXxx()和getXxx();getDeclaredXxx()可以获取所有包括私有的
获取类的结构
package com.jikedaquan.reflection;import java.lang.annotation.Annotation;import java.lang.reflect.Constructor;import java.lang.reflect.Field;import java.lang.reflect.Method;public class GetClassStruct { public static void main(String[] args) { try { Class clz=Class.forName("com.jikedaquan.reflection.User"); System.out.println("===========构造==========="); //获取构造方法 Constructor[] cons=clz.getDeclaredConstructors(); for (Constructor constructor : cons) { System.out.println(constructor); } //获取字段 System.out.println("===========字段==========="); Field[] fields=clz.getDeclaredFields(); for (Field field : fields) { System.out.println(field); } //获取方法 System.out.println("===========方法==========="); Method[] methods=clz.getDeclaredMethods(); for (Method method : methods) { System.out.println(method); } //获取父类 System.out.println("===========父类==========="); Class supperClass=clz.getSuperclass(); System.out.println(supperClass.getName()); //获取实现的接口 System.out.println("===========接口==========="); Class[] interfaces=clz.getInterfaces(); for (Class interf : interfaces) { System.out.println(interf); } //获取注解 System.out.println("===========注解==========="); Annotation[] annotations=clz.getAnnotations(); for (Annotation annotation : annotations) { System.out.println(annotation); } } catch (ClassNotFoundException e) { e.printStackTrace(); } } }
作者:极客大全
链接:https://www.jianshu.com/p/3775fbbdfa69
共同学习,写下你的评论
评论加载中...
作者其他优质文章