欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Java中测试和注解概念

程序员文章站 2022-05-29 15:55:13
...

Junit 单元测试(白盒)

  • 测试分类

    • 黑盒测试:不需要写代码,给输入值,看程序是否能够输出期望的值
    • 白盒测试:需要写代码,关注程序具体的执行流程
  • 步骤:

    1. 定义一个测试类(测试用例)
    // 建议
    测试类名: 被测试的类名Test
    包名: xxx.xxx.xx.test
    
    1. 定义测试方法:可以独立运行
    // 建议
    方法名: test测试的方法名
    返回值: void
    参数列表: 空参
    
    1. 给方法加 @Test
    2. 导入 Junit 依赖环境
  • 判定(红色失败,绿色成功)

    • 一般使用断言操作来处理结果
    • Assert.assertEquals(期望的结果,传递的结果);
    @Test
    public void testSub(){
      Calculator c = new Calculator();
      int result = c.sub(1,2);
      Assert.assertEquals(-1,result);
    }
    
  • 补充

    • @Before:修饰的方法会在测试方法之前被自动执行
    • @After:修饰的方法会在测试方法执行之后自动被执行
    /**
     * 初始化方法:
     * 用于资源申请,所有测试方法在执行之前都会先执行该方法
     */
    @Before
    public void init(){
        System.out.println("init...");
    }
    /**
     * 释放资源方法:
     * 在所有测试方法执行完后,都会自动执行该方法
     */
    @After
    public void close(){
        System.out.println("close...");
    }
    

反射

  • 框架设计的灵魂

    • 框架: 半成品软件, 可以在框架的基础上进行软件开发, 简化编码
    • 反射: 将类的各个组成部分封装为其它对象, 这就是反射机制
  • 好处

    1. 可以在程序运行过程中, 操作这些对象
    2. 可以解耦, 提高程序的可扩展性
  • 获取 Class 对象的方式

    1. Source 源代码阶段
      • Class.forName("全类名"):将字节码文件加载进内存, 返回Class对象多用于配置文件, 将类名定义在配置文件中. 读取文件, 加载类
    2. Class 类对象阶段
      • 类名.class :通过类名的属性 class 获取,多用于参数的传递
    3. Runtime 运行时阶段
      • 对象.getClass() : getClass()方法在 Object 类中定义着,多用于对象的获取字节码的方式
    • 结论:同一个字节码文件(*.class)在一次程序运行过程中, 只会被加载一次,不论通过哪一种方式获取的 Class 对象都是同一个
    public static void main(String[] args) throws Exception {
        // 1.Class.forNamae("全类名")
        Class cls1 = Class.forName("cn.itcast.domain.Person");
        
        // 2.类名.class
        Class cls2 = Person.class;
        
        // 3.对象.getClass()
        Person p = new Person();
        Class cls3 = p.getClass();
        System.out.println(cls3);
    }
    
  • Class 对象功能

    1. 获取成员变量们
      • Field[] getFields():获取所有 public 修饰的成员变量
      • Field getField(String name)
      • Field[] getDeclaredFields():获取所有的成员变量, 不考虑修饰符
      • Field getDeclaredFields(String name):不能访问私有, 但可以暴力反射
    Class personClass = Person.class;
    // (1)------------------------------
    Field[] fields = personClass.getFields();
    
    // (2)------------------------------
    Field a = personClass.getField("a");
    Person p = new Person();
    // 获取成员变量 a 的值
    Object value = a.get(p);
    sout(value);
    // 设置 a 的值
    a.set(p,"张三");
    sout(p);
    
    // (3)------------------------------
    Field[] declaredFields = person.getDeclaredFields();
    // foreach...
    
    // (4)------------------------------
    Field d = person.getDeclaredFields("d");
    d.setAccessible(true);  //忽略访问权限修饰符的安全检查, 暴力反射
    Object value2 = d.get(p);
    sout(value2);
    
    1. 获取构造方法们
      • Constructor<?>[] getConstructors()
      • Constructor<T> getConstructors(类<?>... parameterTypes)
      • Constructor<T> getDeclaredConstructor(类<?>... parameterTypes)
      • Constructor<?>[] getDeclaredConstructors()
    /* 
    	创建对象
    	T newInstance(Object... initargs)
    	如果使用空参数构造方法创建对象, 操作可以简化: Class 对象的 newInstance 方法
    */
    
    // Constructor<T> getConstructor(类<?>... parameterTypes)
    Constructor constructor = personClass.getConstructor(String.class, int.class);
    System.out.println(constructor);
    // 创建对象
    Object person = constructor.newInstance("张三", 23);
    System.out.println(person);
    
    Object o = personClass.newInstance();
    System.out.println(o);
    
    1. 获取成员方法们
      • Method[] getMethods()
      • Method getMethod(String name, 类<?>... parameterTypes)
      • Method[] getDeclaredMethods()
      • Method getDeclaredMethod(String name, 类<?>... parameterTypes)
    /*
    	执行方法
    	Object invoke(Object obj, Object...args)
    	获取方法名称
    	String getName
    */
    
    // 获取指定名称的方法
    Method eat_method = personClass.getMethod("eat");
    Person p = new Person();
    // 执行方法 无参
    eat_method.invoke(p);
    
    Method ea_method2 = personClass.getMethod("eat",String.class);
    // 执行方法 有参
    eat_method2.invoke(p,"饭");
    
    1. 获取类名
      • String getName()
    // 获取类名
    String className = personClass.getName();
    System.out.println(className);
    

注解

  • 说明程序的,给计算机看

  • @注解名称

  • 预定义的注解

    • @Override:检测被该注解标注的方法是否是继承自父类(接口)的
    • @Deprecated:该注解标注的内容, 表示已过时
    • @SuppressWarnings:压制警告
      • 一般传递参数 all
      • @SuppressWarnings(“all”)
  • 自定义注解

    • 格式(元注解)

      • public @interface 注解名称{}
    • 本质:注解本质上就是一个接口, 该接口默认继承 Annotation 接口

      • public interface 注解名称 extends java.lang.annotation.Annotation{}
    • 属性:接口中可以定义的成员方法

      • 要求

        1. 属性的返回值类型

          1. 基本数据类型
          2. String
          3. 枚举
          4. 注解
          5. 以上类型的数组
          int show1();
          String show2();
          
          Person per();
          MyAnno anno2();
          
          String[] strs();
          
        2. 定义了属性, 在使用时需赋值

          1. 默认赋值
            • String name() default "张三";
          2. 使用时赋值
          3. 注意
            1. 如果定义属性时, 使用 default 关键字给属性默认初始化值, 则使用注解时, 可以不进行属性的赋值
            2. 如果只有一个属性需要赋值, 并且属性的名称是 value, 则 value 可以省略, 直接定义值即可
            3. 数组赋值时, 值使用{}包裹; 如果数组中只有一个值, 则{}可以省略
    • 元注解(用于描述注解的注解)

      • @Target:描述注解能够作用的位置
        • ElementType 取值
          • TYPE:可以作用于类上
          • METHOD:可以作用于方法上
          • FIELD:可以作用于成员变量上
        • @Target(value={ElementType.TYPE,ElementType.METHOD,ElementType.FIELD})
      • @Retention:描述注解被保留的阶段
        • @Retention(RetentionPolicy.RUNTIME):当前被描述的注解, 会保留到 class 字节码文件中, 并被 JVM 读取到
      • @Documented:描述注解是否被抽取到 api 文档中
      • @Inherited:描述注解是否被子类继承
  • 在程序中使用(解析)注解

    // 1.获取注解定义的位置对象 (Class,Method,Field)
    // 2.获取指定的注解
    getAnnotation(Class) // 其实就是在内存中生成了一个该注解接口的子类实现对象
    
    public class ProImpl implements Pro{
        public String className(){
            return "cn.xxx.annotation.Demo1";
        }
        public String methodName(){
            return "show";
        }
    }
    // 3.调用注解中的抽象方法获取配置的属性值
    
    // 1.解析注解
    // 1.1 获取该类的字节码文件对象
    Class<RefkectTest> reflectTestClass = ReflectTest.class;
    // 2.获取上边的注解对象
    // 其实就是在内存中生成了一个该注解接口的子类实现对象
    Pro an = reflectTestClass.getAnnotation(Pro.class);
    // 3.调用注解对象中定义的抽象方法,获取返回值
    String className = an.className();
    
相关标签: 操作手册 java

上一篇: HTML&CSS知识点

下一篇: 3.表的创建