Java高级技术

单元测试

概述、Junit框架快速入门

  1. 单元测试
    • 就是针对最小的单元(方法),编写测试代码对其进行正确性测试
  2. 之前是如何进行单元测试的?存在什么问题?
    • 只能在main方法编写测试代码,去调用其他方法进行测试
    • 无法实现自动化测试。一个方法测试失效,可能影响其他方法的测试
    • 无法得到测试的报告,需要程序员自己去观察测试是否成功
  3. Junit单元测试框架
    • 可以用对方进行测试,他是第三方公司开源出来的(很多开发工具已经集成了Junit框架,比如IDEA)
  4. 优点
    • 可以灵活的编写测试代码,可以针对某个方法执行测试,也支持一键完成对全部方法的自动化测试,且各自独立
    • 不需要程序员去分析测试的结果,会自动生成测试报告出来
  5. 具体步骤:
    • 将Junit框架的jar包导入到项目中(注意:IDEA继承了Junit框架,不需要我们自己手工导入了)
    • 为需要测试的业务类,定义对应的测试类,并未每个业务方法,编写对应的测试方法(必须:公共、无参、无返回值)
    • 测试方法上必须声明@Test注解,然后在测试方法中,编写代码调用被测试的业务方法进行测试
    • 开始测试:选中测试方法,右键选择“Junit运行”,如果测试通过则是绿色;如果测试失败,则是红色
  6. Junit断言机制:
    • Assert.assertEquals(String message, long expected, long actual);
    • 程序员可以通过该方法预测业务方法的结果

Junit框架的常见注解

  1. Junit单元测试框架的常见注解(Junit 4.xxxx版本)

    注释 说明
    @Test 测试类中的方法必须用它修饰才能成为测试方法,才能启动执行
    @Before 用来修饰一个实例方法,该方法会在每一个测试方法执行前执行一次
    @After 用来修饰一个实例方法,该方法会在每一个测试方法执行后执行一次
    @BeforeClass 用来修饰一个静态方法,该方法会在所有测试方法执行前只执行一次
    @AfterClass 用来修饰一个静态方法,该方法会在所有测试方法执行后只执行一次
    • 在测试方法执行前执行的方法,常用于初始化资源
    • 在测试方法执行完后再执行的方法,常用于:释放资源
  2. Junit单元测试框架的常见注解(Junit 5.xxxx版本)

    注释 说明
    @Test 测试类中的方法必须用它修饰才能成为测试方法,才能启动执行
    @BeforeEach 用来修饰一个实例方法,该方法会在每一个测试方法执行前执行一次
    @AfterEach 用来修饰一个实例方法,该方法会在每一个测试方法执行后执行一次
    @BeforeAll 用来修饰一个静态方法,该方法会在所有测试方法执行前只执行一次
    @AfterAll 用来修饰一个静态方法,该方法会在所有测试方法执行后只执行一次
    • 在测试方法执行前执行的方法,常用于初始化资源
    • 在测试方法执行完后再执行的方法,常用于:释放资源

反射 (Reflection)

认识反射、获取类

  1. 反射:反射就是加载类,并允许以编程的方式解剖类中的各种成分(成员变量、方法、构造方法等)
  2. 反射学什么:学习获取类的信息、操作他们
    • 反射第一步:加载类,获取类的字节码:Class对象
    • 获取类的构造器:Constructor对象
    • 获取类的成员方法:Field对象
    • 获取类的成员方法:Method对象
  3. 获取Class对象的三种方式:
    • Class c1 = 类名.class
    • 调用Class提供的方法:public static Class forName(String packet)
    • Object提供的方法:public Class getClass(); Class c3 = 对象.getClass();

获取类的构造器

  1. Class提供了从类中获取构造器的方法。

    方法名称 说明
    Constructor<?>[] getConstructors() 获取全部构造器(只能获取public修饰)
    Constructor<?>[] getDeclaredConstructors() 获取全部构造器(只要存在就能拿到)
    Constructor<?> getConstructor(Class<?>... parameterTypes) 获取某个构造器(只能获取public修饰)
    Constructor<?> getDeclaredConstructor(Class<?>... parameterTypes) 获取全部构造器(只要存在就能拿到)
  2. 获取类的构造器的作用:依然是初始化对象返回

    Constructor提供的方法 说明
    T newInstance(Object... initargs) 调用此构造器对象表示构造器,并传入参数,完成对象的初始化并返回
    public void setAccessible(boolean flag) 设置为true,表示禁止检查访问控制(暴力反射)

获取类的成员变量

  1. Class提供了从类中获取成员变量的方法

    方法名称 说明
    public Field[] getFields() 获取类的全部成员变量(只能获取public修饰)
    public Field[] getDeclaredFields() 获取类的全部成员变量(只要存在就能拿到)
    public Field getField(String name) 获取类的某个成员变量(只能获取public修饰)
    public Field getDeclaredField(String name) 获取类的某个成员变量(只要存在就能拿到)
  2. 获取到成员变量作用:依然是赋值、取值

    方法名称 说明
    void set(Object obj, Object value) 赋值
    Object get(Object obj) 取值
    public void setAccessible(boolean flag) 设置true,表示禁止检查访问权限(暴力反射)

获取类的成员方法

  1. Class提供了从类中获取成员方法的API

    方法名称 说明
    Method[] getMethods() 获取类的全部成员方法(只能获取public修饰)
    Method[] getDeclaredMethods() 获取类的全部成员方法(只要存在就能拿到)
    Method getMethod(String name, Class<?>... parameterType) 获取类的某个成员方法(只能获取public修饰)
    Method getDeclaredMethod(String name, Class<?>... parameterType) 获取类的某个成员方法(只要存在就能拿到)
  2. 获取成员方法的作用:依然是执行

    Method提供的方法 说明
    public Object invoke(Object obj, Object... args) 触发某个对象的该方法执行
    public void setAccessible(boolean flag) 设置true,表示禁止检查访问权限(暴力反射)

作用、应用场景

  1. 反射的作用:
    • 基本作用:可以得到一个类的全部成分然后操作
    • 可以破坏封装性
    • 最重要的用途:适合做Java的框架,基本上,主流的框架都会基于反射设计出一些通用的功能

注解

概述、自定义注解

  1. 注解(Annotation)

    • 就是Java代码里的特殊标记,比如:OverrideTest等,作用是:让其他程序根据注解信息来决定怎么执行该程序
    • 注意:注解可以用在类上、构造器上、方法上、成员变量上、参数上等位置处
  2. 自定义注解

    • 就是自己定义注解

      1
      2
      3
      public @interface 注解名称 {
      public 属性名称 属性名() default 默认值 ;
      }
  3. 特殊属性名:value

    • 如果注解中只有一个value属性,使用注解时,value名称可以不写
  4. 注解的原理:

    • 本质是一个接口,继承了Annotation接口
    • @注解(...),相当于创建一个实现类对象,实现了该接口

元注解

  1. 元注解:修饰注解的注解

    1
    2
    3
    4
    @Target(ElementType.METHOD)   // 元注解
    public @interface Test {

    }
  2. 常见的元注解

    • @Target
    • @Retention
  3. @Target({ElementType.METHOD}):声明被修饰的注解只能在哪些位置使用

    • Type:类,接口
    • FIELD:成员变量
    • METHOD:成员方法
    • PARAMETER:方法参数
    • CONSTRUCTOR:构造器
    • LOCAL_VARIABLE:局部变量
  4. @Retention(RetentionPolicy.RUNTIME):声明注解的保留周期

    • SOURCE:只作用在源码阶段,字节码文件中不存在
    • CLASS(默认值):保留到字节码文件阶段,运行阶段不存在
    • RUNTIME(开发常用):一直保留到运行阶段

注解的解析

  1. 什么是注解的解析:

    • 就是判断类上、方法上、成员变量上是否存在注解,并把注解里的内容给解析出来
  2. 如何解析注解:

    • 指导思想:要解析谁上面的注解,就应该先拿到谁

    • 比如要解析类上面的注解,则应该先获取该类的Class对象,再通过Class对象解析其上面的注解。

    • 比如要解析成员方法上的注解,则应该获取到成员方法的Method对象,再通过Method对象解析其上面的注解。

    • ClassMethodFieldConstructor都实现了AnnotatedElement接口,他们都拥有解析注解的能力

    • AnnotatedElement接口提供了解析注释的方法

      方法名称 说明
      public Annotation[] getDeclaredAnnotations() 获取当前对象上面的注解
      public T getDeclaredAnnotation(Class<T> annotationClass) 获取指定的注解对象
      public boolean isAnnotationPresent(Class<T> annotationClass) 判断当前对象是否存在某个注解

应用场景

  1. 结合反射等技术做框架

动态代理

  1. 程序为什么需要代理?代理长什么样?

    • 对象如果嫌身上干的事太多的话,可以通过代理来转移部分职责
    • 对象有什么方法想被代理,代理就一定要有对应的方法
  2. 如何为Java对象创建一个代理对象?

    • java.lang.reflect.Proxy类:提供了为对象产生代理对象的方法:

      1
      2
      3
      4
      public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
      // 参数一:用于指定用哪个类加载器,去加载生成的代理类
      // 参数二:指定接口,这些接口用于指定生成的代理长什么样,也就是有哪些方法
      // 参数三:用来指定生成的代理对象要干些什么
  • Copyright: Copyright is owned by the author. For commercial reprints, please contact the author for authorization. For non-commercial reprints, please indicate the source.
  • Copyrights © 2023-2024 LittleWin
  • Visitors: | Views:

请我喝杯咖啡吧~

支付宝
微信