第四部分 反射

76 阅读3分钟

第四部分

56 反射

反射是指在程序运行过程中,对任意一个类都能获取所有的属性和方法,对任意一个对象都能调用其任意一个方法。这种动态获取类和对象的属性和信息,以及动态调用对象的方法的功能称为Java的反射机制

反射API

  • Class类:用于获取类的属性和方法等
  • Field类:表示类的成员变量,用于获取和设置类中的属性值
  • Method类:表示类的方法,用于获取方法的描述信息和执行方法
  • Constructor类:表示类的构造方法

反射的使用步骤

  1. 获取想要操作的类的Class对象,这是反射的核心
  2. 调用Class对象所对应的类的方法,这是反射的使用阶段
  3. 使用反射API获取并调用类的属性和方法等信息
获取Class对象的三种方法
// 第一种:通过对象的getClass()方法获取
Person p = new Person();
Class clz = p.getClass();
// 第二种:通过类的Class属性获取
Class clz = Person.class;
// 第三种:通过Class类的静态方法forName()获取
Class clz = Class.forName("xx.xx.Person");
在获取Class对象后,可以获取类的属性和方法
// 获取Class对象
Class clz = Class.forName("fullClassName");
// 获取所有的属性
Field[] fields = clz.getDeclaredFields();
// 获取所有的方法
Method[] methods = clz.getDeclaredMethods();
// 获取所有的构造器
Constructor[] constructors = clz.getDeclaredConstructors();
创建对象的两种方法
// 通过Class对象的newInstance(),要求该类有空参的构造函数

// 通过Class对象获取指定的构造方法对象,再通过构造方法调用newInstance方法创建对象
Class clz = Class.forName("fullClassName");
Constructor c = clz.getDeclaredConstructor(String.class, String.class);
Person p = (Person)c.newInstance("dachui", "man");
Method的invoke方法
Class clz = Class.forName("fullClassName");
Object object = clz.newInstance();
Method setName = clz.getMethod("setName", String.class);
serName.invoke(object, "dachui");

58 序列化

序列化为了保存在内存中的各种对象的状态(也就是实例变量,不是方法),并且可以把保存的对象状态再读出来

类要实现序列化,只需要继承java.io.Serializable接口即可

序列化并不保存类的静态变量以及transient修饰的变量

59 动态代理及其应用

当想要给实现了某个接口的类的方法增加一些额外的处理,例如加事务,加日志等,可以给这个类创建一个代理,顾名思义就是创建一个新的类,这个类不仅包含了原来类的方法的功能,还在原理的基础上增添了额外的处理。代理类不是定义的,是动态生成的。具有解耦意义,灵活,扩展性强

应用:加事务,加日志,加权限,String的AOP

60 怎样实现动态代理

首先必须定义一个接口,还要有一个InvocationHandler(将实现接口的类的对象传递给它)处理类。再有一个工具类Proxy(习惯性将其称为代理类,因为调用他的newInstance()可以产生代理对象,其实他只是一个产生代理对象的工具类)。利用到InvocationHandler,拼接代理类源码,将其编译生成代理类的二进制码,利用加载器加载,并将其实例化产生代理对象,最后返回。