十七、单元测试、反射、注解、动态代理
-
单元测试概述
-
单元测试就是针对最小的功能单元编写测试代码,Java程序最小的功能单元就是方法,因此,单元测试就是针对Java方法的测试,进而检查方法的正确性。
-
Junit单元测试框架
-
Junit是使用Java语言实现的单元测试框架,它是开源的,Java开发者都应当学习并使用Junit编写单元测试
-
此外,几乎所有的IDE工具都集成了Junit,这样我们就可以直接在IDE中编写并运行Junit测试,Junit目前最新版本是5
-
-
Junit优点
-
Junit可以灵活的选择执行哪些测试方法,可以一键执行全部测试方法
-
Junit可以生成全部方法的测试报告。
-
单元测试中的某个方法测试失败了,不会影响其他测试方法的测试
-
-
-
单元测试快速入门
-
junit-reflect-annotation-proxy-app.src.com.itheima.d1_junit
-
-
单元测试常用注解
-
Junit常用注解(Junit 4.xxxx版本)
-
注解 说明 @Test 测试方法 @Before 用来修饰实例方法,该方法会在每一个测试方法执行之前执行一次 @After 又来修饰实例方法,该方法会在每一个测试方法执行之后执行一次 @BeforeClass 用来修饰静态方法,该方法会在所有测试方法执行之前只执行一次 @AfterClass 用来修饰静态方法,该方法会在所有测试方法执行之后只执行一次 -
开始执行的方法:初始化资源
-
执行完之后的方法:释放资源
-
-
Junit常用注解(Junit 5.xxxx版本)
-
注解 说明 @Test 测试方法 @BeforeEach 用来修饰实例方法,该方法会在每一个测试方法执行之前执行一次 @AfterEach 又来修饰实例方法,该方法会在每一个测试方法执行之后执行一次 @BeforeAll 用来修饰静态方法,该方法会在所有测试方法执行之前只执行一次 @AfterAll 用来修饰静态方法,该方法会在所有测试方法执行之后只执行一次 -
开始执行的方法:初始化资源
-
执行完之后的方法:释放资源
-
-
反射
-
反射的概述
-
反射是指对于任何一个Class类,在“运行的时候”都可以直接得到这个类全部成分
-
在运行时,可以直接得到这个类的构造器对象:Constructor
-
在运行时,可以直接得到这个类的成员变量对象:Field
-
在运行时,可以直接得到这个类的成员方法对象:Method
-
这种运行时动态获取类信息以及动态调用类中成分的能力称为Java语言的反射机制
-
反射类的关键:
-
反射的第一步都是先得到编译后的Class类对象,然后就可以得到Class的全部成分
-
-
-
反射获取类对象
-
反射的第一步:获取Class类的对象
-
-
反射获取构造器对象
-
使用反射技术获取构造器对象并使用
-
反射的第一步是先得到类对象,然后从类对象中获取类的成分对象
-
Class类中用于获取构造器的方法
-
方法 说明 Constructor<?>[] getConstructors() 返回所有构造器对象的数组(只能拿public的) Constructor<?>[] getDeclaredConstructors() 返回所有构造器对象的数组,存在就能拿到 Constructor<T> getConstructor(Class<?>… parameterTypes) 返回单个构造器对象(只能拿public的) Constructor<T> getDeclaredConstructor(Class<?>… parameterTypes) 返回单个构造器对象,存在就能拿到 -
获取构造器的作用依然是初始化一个对象返回
-
-
Constructor类中用于创建对象的方法
-
符号 说明 T newInstance(Object… initargs) 根据指定的构造器创建对象 public void setAccessible(boolean flag) 设置true,表示取消访问检查,进行暴力反射
-
-
反射获取成员变量对象
-
反射的第一步是先得到类对象,然后从类对象中获取类的成分对象
-
Class类中用于获取成员变量的方法
-
方法 说明 Field[] getFields() 返回所有变量对象的数组(只能拿public的) Field[] getDeclaredFields() 返回所有成员变量对象的数组,存在就能拿到 Field getField(String name) 返回单个成员变量对象(只能那public的) Field getDeclaredField(String name) 返回单个成员变量对象,存在就能拿到 -
获取成员变量的作用依然是在某个对象中取值、赋值
-
-
Field类中用于取值、赋值的方法
-
符号 说明 void set(Object obj,Object value): 取值 Object get(Object obj) 获取值
-
-
-
反射获取方法对象
-
反射的第一步是先得到类对象,然后从类对象中获取类的成分对象
-
Class类中用于获取成员方法的方法
-
方法 说明 Method[] getMethods() 返回所有成员方法对象的数组(只能拿public的) Method[] getDeclaredMethods() 返回所有成员方法对象的数组,存在就能拿到 Method getMethod(String name, Class<?>… parameterTypes) 返回单个成员方法对象(只能拿public的) Method getDeclaredMethod(String name, Class<?>… parameterTypes) 返回单个成员方法的对象,存在就能拿到
-
-
使用反射技术获取方法对象并使用
-
获取成员方法的作用依然是在某个对象中进行执行此方法
-
-
Method类中用于触发执行的方法
-
符号 说明 Object invoke(Object obj, Object… args) 运行方法:参数一:用obj对象调用该方法 参数二:调用方法的传递的参数(如果没有就不写) 返回值:方法的返回值(如果没有就不写)
-
-
-
反射的作用 - 绕过编译阶段为集合添加数据
-
反射是作用在运行时的技术,此时集合的泛型将不能产生约束了,此时是可以为集合存入其他任意类型的元素的
-
泛型只是在编译阶段可以约束集合只能操作某种数据类型,在编译成Class文件进入运行阶段的时候,其真实类型都是ArrayList了,泛型相当于被擦除了
-
-
反射的作用 - 通用框架的底层原理
-
junit-reflect-annotation-proxy-app.src.com.itheima.d7_reflect_framework
-
注解
-
注解概述
-
Java注解(Annotation)又称Java标注,是JDK5.0引入的一种注释机制
-
Java语言中的类、构造器、方法、成员变量、参数等都可以被注解进行标注
-
注解的作用:
-
对Java中类、方法、成员变量做标记,然后进行特殊处理,至于到底做何种处理由业务需求来决定
-
-
-
自定义注解
-
就是自己做一个注解来使用
-
格式:public @interface 注解名称{public 属性类型 属性名() default 默认值;}
-
特殊属性:
-
value属性,如果只有一个value属性的情况下,使用value属性的时候可以省略value名称不写
-
但是如果有多个属性,且多个属性没有默认值,那么value名称是不能省略的
-
-
-
元注解
-
就是注解注解的注解
-
元注解由两个:
-
@Target:约束自定义注解只能在哪些地方使用
-
@Target中可使用的值定义在ElementType枚举类中,常用值如下:
-
TYPE,类,接口
-
FIELD,成员变量
-
METHOD,成员方法
-
PARAMETER,方法参数
-
CONSTRUCTOR, 构造器
-
LOCAL_VARIABLE,局部变量
-
-
@Retention:申明注解的生命周期
-
@Retention中可以使用的值定义在RetentionPolicy枚举类中,常用值如下:
-
SOURCE:注解之作用在源码阶段,生成的字节码文件中不存在
-
CLASS:注解作用在源码阶段,字节码文件阶段,运行阶段不存在,默认值
-
RUNTIME:注解作用在源码阶段,字节码文件阶段,运行阶段(开发常用)
-
-
-
-
注解解析
-
注解的操作中经常需要进行解析,注解的解析就是判断是否存在注解,存在注解就解析除内容
-
于注解解析相关的接口
-
Annotation:注解的顶级接口,注解都是Annotation类型的对象
-
AnnotatedElement:该接口定义了与注解解析相关的解析方法
-
方法 说明 Annotation[] getDeclaredAnnotation() 获得当前对象上使用的所有注解,返回注解数组 T getDeclaredAnnotation(Class<T> annotationClass) 根据注解类型获得对应注解对象 boolean isAnnotationPresent(Class<Annotation> annotationClass) 判断当前对象是否使用了指定的注解,如果使用了则返回true,否则返回false -
所有的类成分Class,Method,Field,Constructor,都实现了AnnotatedElement接口他们都拥有解析注解的能力
-
-
解析注解的技巧
-
注解在哪个成分上,我们就先拿哪个成分对象
-
比如注解作用成员方法,则要获得该成员方法对应的Method对象,在来拿上面的注解
-
比如注解作用在类上,则要该类的Class对象,再来那上面的注解
-
比如注解作用在成员变量上,则要获得该成员变量对应的Field对象,再来那上面的注解
-
-
-
注解的应用场景一:Junit框架
-
junit-reflect-annotation-proxy-app.src.com.itheima.d8_annotation.AnnotationDemo4
-
动态代理
-
动态代理概述、快速入门
-
代理:某些场景下对象会找一个代理对象,来辅助自己完成一些工作,如:歌星(经纪人),买发的人(房产中介)
-
代理主要是对对象的行为额外做一些辅助操作。
-
如何创建代理对象
-
Java中代理的代表类:java.lang.reflect.Proxy
-
Proxy提供了一个静态方法,用于为对象产生一个代理对象返回
-
-
public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h)
-
为对象返回一个代理对象
-
参数一:定义代理类的类加载器
-
参数二:代理类要实现的接口列表
-
参数三:将方法调用分派到的处理程序。(代理对象的核心处理程序)
-
-
-
动态代理的应用案例:做性能分析、代理的好处小结
-
优化的关键步骤
-
必须有接口,实现类要实现接口(代理通常是基于接口实现的)
-
创建一个实现类的对象,该对象为业务对象,紧接着为业务对象做一个代理对象
-
-
动态代理的优点
-
可以在不改变方法源码的情况下,实现对方法功能的增强,提高了代码的复用
-
简化了编程工作、提高了开发效率,同时提高了软件系统的可扩展性
-
可以为被代理对象的所有方法做代理
-
非常的灵活,支持任意接口类型的实现类对象做代理,也可以直接为接口本身做代理
-
-
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)