首页 > 编程语言 >Java学习笔记——第二十二天

Java学习笔记——第二十二天

时间:2024-03-21 12:11:59浏览次数:34  
标签:第二十二 Java 对象 代理 笔记 注解 方法 Class 测试方法

Java高级技术

单元测试

概述

单元测试就是针对最小的功能单元(方法),编写测试代码对该功能进行正确性测试。

目前的测试方法是怎样的,存在什么问题

  • 只能编写main方法,并在main方法中再去调用其他方法进行测试。
  • 使用起来很不灵活,无法实现自动化测试。
  • 无法得到测试的报告,需要程序员自己去观察测试是否成功。

Junit单元测试框架

JUnit是使用Java语言实现的单元测试框架,它是第三方公司开源出来的,很多开发工具已经集成了Junit框架,比如IDEA。

优点

  • 编写的测试代码很灵活,可以指定某个测试方法执行测试,也支持一键完成自动化测试。
  • 不需要程序员去分析测试的结果,会自动生成测试报告出来。
  • 提供了更强大的测试能力。
  • 单元测试中的某个方法测试失败了,不会影响其他测试方法的测试。

具体使用步骤

  1. 将Junit框架的jar包导入到项目中(注意:IDEA集成了Junit框架,不需要我们自己手工导入了)。
  2. 编写测试类、测试类方法(注意:测试方法必须是公共的,无参数,无返回值的非静态方法)。
  3. 必须在测试方法上使用@Test注解(标注该方法是一个测试方法)。
  4. 在测试方法中,编写程序调用被测试的方法即可。
  5. 选中测试方法,右键选择“JUnit运行” ,如果测试通过则是绿色;如果测试失败,则是红色。
  6. 也可以选择类或者模块启动来测试全部方法。

断言机制

  • 可以通过预测测试方法的结果来判断方法是否有bug。
  • 使用Assert类的assertEquals()方法。

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

注解 说明
@Test 测试方法
@Before 用来修饰一个实例方法,该方法会在每一个测试方法执行之前执行一次
@After 用来修饰一个实例方法,该方法会在每一个测试方法执行之后执行一次
@BeforeClass 用来修饰一个静态方法,该方法会在所有测试方法之前只执行一次
@AfterClass 用来修饰一个静态方法,该方法会在所有测试方法之后只执行一次
  • 在测试方法执行前执行的方法,常用于:初始化资源。
  • 在测试方法执行后执行的方法,常用于:释放资源。

Junit单元测试框架的常用注解(Junit 5.xxxx版本)

注解 说明
@Test 测试方法
@BeforeEach 用来修饰一个实例方法,该方法会在每一个测试方法执行之前执行一次
@AfterEach 用来修饰一个实例方法,该方法会在每一个测试方法执行之后执行一次
@BeforeAll 用来修饰一个静态方法,该方法会在所有测试方法之前只执行一次
@AfterAll 用来修饰一个静态方法,该方法会在所有测试方法之后只执行一次
  • 在测试方法执行前执行的方法,常用于:初始化资源。
  • 在测试方法执行后执行的方法,常用于:释放资源。

反射(Reflection)

  • 反射指的是允许以编程的方式访问已加载类的成分(成员变量、方法、构造器等)。
  • 反射的基本作用:在运行时获取类的字节码文件对象,然后可以解析类中的全部成分。
  • 反射的核心思想和关键就是:得到编译以后的class文件对象。

反射的内容

  1. 反射第一步:获取类:Class
  2. 获取类的构造器:Constructor
  3. 获取类的成员变量:Field
  4. 获取类的成员方法:Method

获取类

反射的第一步都是先得到加载后的类,然后才可以去拿类的其他成分。

获取Class类的对象的三种方式

  • 方式一:Class c1 = Class.forName("全类名");
  • 方式二:Class c2 = 类名.class;
  • 方式三:Class c3 = 对象.getClass();

获取构造器

步骤

  1. 获得class对象。
  2. 获得Constructor对象。
  3. 创建对象。

Class类中用于获取构造器Constructor类的方法

方法 说明
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,表示取消访问检查,进行暴力反射
  • 反射可以破坏封装性,私有的构造器也可以执行了。

获取成员变量

步骤

  1. 获得class对象。
  2. 获得Field对象。
  3. 赋值或者取值。

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) 取值
public void setAccessible(boolean flag) 设置为true,表示取消访问检查,进行暴力反射

获取成员方法

步骤

  1. 获得class对象。
  2. 获得Method对象。
  3. 运行方法。

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) 运行方法:
参数一:调用该方法的对象
参数二:给该方法传递的参数(如果没有就不写)
返回值:方法的返回值(如果没有就不写)
public void setAccessible(boolean flag) 设置为true,表示取消访问检查,进行暴力反射

反射的作用

  • 可以在运行时得到一个类的全部成分然后操作。
  • 可以破坏封装性。
  • 也可以破坏泛型的约束性(编译时会进行泛型擦除)。
  • 更重要的用途是适合:做Java高级框架。
  • 基本上主流框架都会基于反射设计一些通用技术功能。

注解

概述

  • Java 注解(Annotation)又称 Java 标注,是 JDK5.0 引入的一种注释机制。
  • Java 语言中的类、构造器、方法、成员变量、参数等都可以被注解进行标注。

自定义注解

自定义注解就是自己做一个注解来使用。

格式

public @interface 注解名称 {
    public 属性类型 属性名() default 默认值; 
}
  • 属性类型:Java支持的数据类型基本上都支持。
  • public可以不写,会默认加上。

使用格式

@注解名称(属性名=属性值,...) //没有默认值的属性必须赋值

特殊属性名:value

  • 如果只有一个value属性的情况下,使用value属性的时候可以省略value的属性名不写。
  • 如果除value外的属性都有默认值且其他属性都不用赋值,那么也可以省略value的属性名不写。
  • 但是如果有多个属性, 且存在某个或某些属性没有默认值,那么value的属性名是不能省略的。

注解的原理

  • 注解本质是一个接口,Java中所有注解都是继承了Annotation接口的。
  • @注解(...)其实就是创建了一个实现类对象,实现了该注解以及Annotation接口。

元注解

元注解就是注解注解的注解。

元注解的类型

元注解有两个: @Target和 @Retention。

@Target(ElementType.类型)

作用:声明被修饰的注解只能在哪些位置使用。

  • TYPE,类,接口

  • FIELD,成员变量

  • METHOD, 成员方法

  • PARAMETER,方法参数

  • CONSTRUCTOR,构造器

  • LOCAL_VARIABLE,局部变量

@Retention(RetentionPolicy.类型)

作用:声明注解的保留周期。

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

注解的解析

注解的解析就是判断类上、方法上和成员变量上是否存在注解,并把注解里的内容给解析出来。

解析注解的指导思想

  • 要解析谁上面的注解,就应该先拿到谁。

  • 与注解解析相关的接口:

    • Annotation:注解的顶级接口,注解都是Annotation类型的对象。
    • AnnotatedElement:该接口定义了与注解解析相关的解析方法。
  • 所有的类成分Class,Method,Field和Constructor都实现了AnnotatedElement接口,他们都拥有解析注解的能力

方法 说明
Annotation[] getDeclaredAnnotations() 获得当前对象上使用的所有注解,返回注解数组。
T getDeclaredAnnotation(Class<T> annotationClass) 根据注解类型获得对应注解对象
boolean isAnnotationPresent(Class<Annotation> annotationClass) 判断当前对象是否使用了指定的注解,如果使用了则返回true,否则返回false

应用场景

配合反射等技术做框架。

动态代理

概述

代理思想

被代理者没有能力,或者不愿意去完成某件事情,需要找个人(代理)代替自己去完成这件事。

代理

代理就是一个对象,用来对被代理对象的行为进行管理的对象。

动态代理的作用

动态代理主要是对被代理对象的行为进行代理。

动态代理的开发步骤

  1. 必须定义接口,里面定义一些行为,用来约束被代理对象和代理对象都要完成的事情。
  2. 定义一个实现类实现接口,这个实现类的对象代表被代理的对象。
  3. 定义一个测试类,在里面创建被代理对象,然后为其创建一个代理对象返回。(重点)
  4. 代理对象中,需要模拟收首付款,真正触发被代理对象的行为,然后接收尾款操作。
  5. 通过返回的代理对象进行方法的调用,观察动态代理的执行流程。

创建代理对象

Java中代理的代表类是:java.lang.reflect.Proxy,它提供了一个静态方法,用于为被代理对象产生一个代理对象返回。

public static Object newProxyInstance(ClassLoader loader,
                                      Class<?>[] interfaces,
                                      InvocationHandler h) 
作用:为被代理对象返回一个代理对象。
参数一:用于指定类加载器,来加载代理类,产生代理对象,使用当前类名.class.getClassLoader()即可。
参数二:真实业务对象的接口。(被代理的方法交给代理对象)
参数三:代理的核心处理程序。

通过代理对象调用方法的执行流程

  1. 先走向代理。
  2. 代理中的invoke()方法执行。
  3. 回到代理中,由代理负责返回结果给调用者。

动态代理的优点

  1. 可以在不改变方法源码的情况下,实现对方法功能的增强,提高了代码的复用。
  2. 简化了编程工作,提高了开发效率,同时提高了软件系统的可扩展性。
  3. 可以为被代理对象的所有方法做代理。
  4. 非常的灵活,支持任意接口类型的实现类对象做代理,也可以直接为接口本身做代理。

标签:第二十二,Java,对象,代理,笔记,注解,方法,Class,测试方法
From: https://www.cnblogs.com/zgg1h/p/18087076

相关文章

  • ArrayIndexOutOfBoundException and NegativeArraySizeException in Java
    ArrayIndexOutOfBoundExceptionArrayIndexOutOfBoundsException occurswhenweaccessanarray,ora Collection,thatisbackedbyanarraywithaninvalidindex. Thismeansthattheindexiseitherlessthanzeroorgreaterthanorequaltothesizeofthe......
  • Java 8 内存管理原理解析及内存故障排查实践
    作者:vivo互联网服务器团队- ZengZhibin介绍Java8虚拟机的内存区域划分、内存垃圾回收工作原理解析、虚拟机内存分配配置,介绍各垃圾收集器优缺点及场景应用、实践内存故障场景排查诊断,方便读者面临内存故障时有一个明确的思路和方向。一、背景Java是一种流行的编程语言,可......
  • Java基础内容:第七章面向对象(下)编程题详解
            建了一个群:908722740 ,欢迎小伙伴门的加入,平时可以互相学习交流,不管是学习还是工作上的都可以多多交流,本人在校学生,技术有限,错误的地方欢迎指正。目录一、多态案例素材【1】乐手弹奏乐器【2】比萨制作【3】购买饮料二、接口案例素材【1】兔子和青蛙【......
  • Java 面向对象编程进阶四(多态、抽象方法抽象类)
    目录多态(polymorphism)多态和类型转换对象的转型(casting) 类型转换异常向下转型中使用instanceof final关键字抽象方法和抽象类抽象类和抽象方法的基本用法多态(polymorphism)        多态指的是同一个方法调用,由于对象不同可能会有不同的行为。现实......
  • 数字图像处理学习笔记(一)
    数字图像处理学习笔记(一)digital_image_process说明内容列表(已完成)第一章绪论第二章基本原理Matlab支持图片格式图像操作数据类图像类型数据类与图像数据类型间的转换数组索引例2.5标准数组运算符代码优化单元数组与结构体digital_image_process数字图像处理学习......
  • 【设计模式】Java 设计模式之责任链模式(Chain of Responsibility)
    责任链模式(ChainofResponsibility)一、概述责任链模式是一种行为设计模式,它允许请求在对象链中传递。每个对象都有机会处理该请求,并且能将其传递给链中的下一个对象。这种模式为请求创建了一个处理对象的链,并沿着这条链传递该请求,直到有一个对象处理它为止。二、模式结......
  • 【设计模式】Java 设计模式之状态模式(State)
    深入理解状态模式(State)一、概述状态模式是一种行为设计模式,它允许一个对象在其内部状态改变时改变它的行为。对象看起来好像修改了它的类。状态模式把所有的与一个特定的状态相关的行为放到一个类中,并且将请求委托给当前状态对象来执行。在状态模式中,我们创建表示各种状......
  • Java 面向对象编程进阶六(内部类 )
    目录内部类内部类的概念内部类的分类1、非静态内部类(外部类里使用非静态内部类和平时使用其他类没什么不同)2、静态内部类3、匿名内部类4、局部内部类内部类        内部类是一类特殊的类,指的是定义在一个类的内部的类。实际开发中,为了方便的使用外部类的相......
  • Java 面向对象编程进阶七(字符串 String )
    目录字符串StringString基础String类和常量池String类常用的方法String类常用方法一String类常用方法二字符串相等的判断字符串String        String是我们开发中最常用的类,我们不仅要掌握String类常见的方法,对于String的底层实现也需要掌握好......
  • Asp-Net-Core开发笔记:实现动态审计日志功能
    前言最近一直在写Go和Python,好久没写C#,重新回来写C#代码时竟有一种亲切感~说回正题。在当今这个数字化迅速发展的时代,每一个操作都可能对业务产生深远的影响,无论是对数据的简单查询,还是对系统配置的修改。在这样的背景下,审计日志不仅仅是一种遵循最佳实践的手段,更是确......