反射,注解和动态代理,类加载
一、反射
1、概念
- java的反射机制指的是程序在运行过程中,对于类,能获取到类的属性和方法,对于对象,能够调用他的属性和方法,动态的获取数据。
1、获取类的属性和方法
- 假设有一个Student类,
1 | /** |
- 获取类名和属性
1 | import java.lang.reflect.Field; |
- 此外,也可以访问私有方法,通过 class.getDeclaredMethod(“privateMethod”, String.class, int.class)可以获取。
二、注解
- 注解可以使得Java源代码中可以添加功能性的实现代码,还可以添加元数据,和类于接口一样,注解也属于一种类型,使用@interface进行标记,比如定义一个Hello注解
1 | import java.lang.annotation.ElementType; |
- 使用场景,当类,属性和对象标记注解以后,注解的信息提取使用java反射的形式,主要给编译器以及工具类型的软件使用。
2.1 元注解
- 元注解是标记注解的注解,元注解可以指明注解是做什么的,常用的有:
- @Retention 注解的保留期,取值有RetentionPolicy.SOURCE(注解在源码期间保留), RetentionPolicy.CLASS(保留到编译进行的时候,不会加载进jvm) RetentionPolicy.RUNTIME(保留到程序运行时)
- @Document 将注解的元素包含到java doc中
- @Target 注解使用的地方,可以指定类,属性或者方法等,有较多选择
- @Inherited 继承功能,当超类使用了这个注解,他的子类也会使用上这个注解。
- @Repeatable 可重复
三、动态代理
- 代理模式,中间人模式,常见的场景是用户要做一件事情,不会自己亲自做,而是会让中介去做,帮自己实现,面向对象程序设计中很常见的设计模式。代理流程如下:
- 动态代理可以用来做方法的功能增强,对代码无侵入,动态代理使用Proxy的静态方法newProxyInstance动态创建代理,如下
1 | public static Object newProxyInstance(ClassLoader loader,//类加载器 |
- 要创建动态代理,核心是要实现InvocationHandler接口和invoke方法,比如,要为一个接口的功能实现进行日志打印,相关流程:
1 | //动态代理只能为接口创建代理 |
1 | public class HomeWork implements Work{ |
1 | //增强功能 |
1 | import java.lang.reflect.InvocationHandler; |
1 | import java.lang.reflect.Proxy; |
1 | public static void main(String[] args) { |
四、类加载机制
1、概述
- Java代码需要运行,首先需要将源代码进行编译生成 .class 文件,然后 JVM 加载 .class 字节码文件到内存,而 .class 文件是怎样被加载到 JVM 中的就是Java 类加载
2、分类
- AppClassLoader 应用加载器,也称为系统加载器,会加载来自CLASSPATH中的类和包,默认情况下,其它类加载器会将它作为父类加载器
- ExtClassloader 拓展类加载器,主要加载Java的拓展类库
- BootStrapClassLoader 启动类加载器,是最顶层的父类加载器,主要用来加载java的核心类
3、加载过程
- 加载流程如下:
- 加载过程采用双亲委派模型,当一个类加载器收到类加载任务时,会有限交给父类处理,父类无法完成时才会尝试自行加载任务。保证了使用不同的类加载器最终得到的都是同一个对象。