JavaWeb_Day01_Junit单元测试、反射、注解(从入门到秃头)

Junit单元测试

  • 测试分类:
    1.黑盒测试:不需要写代码,给输入值,看程序是否能够输出期望的值
    2.白盒测试:需要写代码,并且需要关注具体的执行流程
    在这里插入图片描述

  • Junit的使用:白盒测试:

    • 步骤

      ​ 1.定义一个测试类(测试用例)

      • 建议:
        • 测试包名:被测试的类名Test 例如:CalculatorTest
        • 包名:xxx.xxx.xxx.test cn.itcast.test

      ​ 2.定义测试方法类:可以独立运行

      • 建议

        • 方法名:test测试类名 testAdd()
        • 返回值:void
        • 参数列表:空参

        3.给方法加@Test

      ​ 4.导入junit依赖环境

      • 判定结果:

        • 红色:失败

        • 绿色:成功

        • 一般我们会使用断言操作处理结果

          • ​ Assert.assertEquals(期望的结果,实际的结果);

代码测试

Calculator类
package cn.itcast.junit;

/*
 * 计算器类
 * */
public class Calculator {

    /**
     * 加法
     *
     * @param a
     * @param b
     * @return
     */
    public int add(int a, int b) {
        return a - b;//此处本应该为加号,现在用作测试为后面报错作铺垫
    }

    /**
     * 减法
     *
     * @param a
     * @param b
     * @return
     */
    public int sub(int a, int b) {
        return a -  b;
    }
}
CalculatorTest类(里面需要写注解@Test 然后导入junit包)

package cn.itcast.test;

import cn.itcast.junit.Calculator;
import org.junit.Assert;
import org.junit.Test;

public class CalculatorTest {
    /**
     * 测试add方法
     */

    @Test
    public void testAdd(){
        System.out.println("我被输入来了");
        //1.创建计算器对象
        Calculator c = new Calculator();
        //2.调用add方法
        System.out.println(c.add(1,2));
        //如果正常运行则是绿色,否则为红色

        //3.断言   我断言这个结果为3
        Assert.assertEquals(3,c.add(1,2));
    }
}
展示结果:

在这里插入图片描述

补充:

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

    /**
     * 释放资源的方法
     * 在所有测试方法执行完毕之后,都会自动执行该方法,不管有没有报错
     */
    @After
    public void close(){
        System.out.println("close...");
    }
测试结果:

在这里插入图片描述

反射:框架设计的灵魂

类从源文件加载到内存再到运行时阶段的展示图:
在这里插入图片描述

  • 框架:半成品软件,可以在框架的基础上进行软件开发,简化编码

  • 反射:将类的各个组成部分封装为其他对象,这就是反射机制

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

    ​ 1.class.forName(“全类名”):将字节码文件加载进内存,返回class对象

    ​ * 多用于配置文件,将类名定义在配置文件中。读取文件,加载类

    ​ 2.类名.class::通过类名的属性class获取

    ​ *多用于参数的传递

    ​ 3.对象.getClass():getClass()方法在Object类中定义着。

    ​ * 多用于对象获取字节码的方式

    • 结论:

      ​ 同一个字节码文件(*.class)在一次程序运行过程中,只会被加载一次,不论通过哪种方式获取的Class对象都是同一个

代码示例:

  /*
         获取class对象的方式:
           1.class.forName("全类名"):将字节码文件加载进内存,返回class对象
           2.类名.class::通过类名的属性class获取
           3.对象.getClass():getClass()方法在Object类中定义着。
         */

        //1.Class.forName("全类名")
        Class cls = Class.forName("cn.itcast.domain.Person");
        System.out.println(cls);
        //2.导入想要获取的类的字节码文件的包中的类;
        Class pc= Person.class;
        System.out.println(pc);
        //3.new一个对象,通过对像的getClass方法来获取字节码文件。
        Person person = new Person();
        System.out.println(person.getClass());
效果展示:在这里插入图片描述
  • Class对象功能:

    • 获取功能:

1.获取成员变量们

  • Field[] getFields() --------- 获取public修饰的成员变量

  • Field[] getField(String name) -----获取指定名称的public修饰的成员变量

  • Field[] getDeclaredFields() -------获取所有的成员变量,不考虑修饰符

  • Field[] getDeclaredField(String name) ------获取单个的成员变量,不考虑修饰符

    2.获取构造方法们

    • Constructor <?> [ ] getConstructors ( )

    • Constructor getConstructor (类<?>. . . parameterTypes)

    • Constructor <?> [ ] getDeclaredConstructors ( )

    • Constructor getDeclaredConstructor (类<?>. . . parameterTypes)

    3.获取成员方法们:

    • Method [] getMethods()

    • Method getMethod(String name, 类<?>… parameterTypes)

    • Method[] getDeclaredMethods()

    • Method getDeclaredMethod(String name, 类<?>… parameterTypes)

    4.获取类名
    String getName()

  • Filed :成员变量

    • 操作:
      • 1.设置值
        • set(Object obj, Object value)
      • 2.获取值
        • get(Object obj)
      • 3.忽略访问权限修饰符的安全检查
        • setAccessablie(true):暴力反射
代码示例:

=ReflectDemo02.java文件===

package cn.itcast.reflect;

import cn.itcast.domain.Person;

import java.lang.reflect.Field;

public class ReflectDemo02 {
    /*
    Class对象功能:
        获取功能:
        1.获取成员变量们
             * Field[] getFields()
             * Field[] getField(String name)

             * Field[] getDeclaredFields()
             * Field[] getDeclaredField(String name)
        2.获取构造方法们
             * Constructor <?> [ ] 	       getConstructors ( )
             * Constructor<T>          getConstructor (类<?>. . . parameterTypes)

             * Constructor <?> [ ] 	 getDeclaredConstructors ( )
             * Constructor<T>          getDeclaredConstructor (类<?>. . . parameterTypes)
        3.获取成员方法们:
             * Method []     getMethods()
             * Method       getMethod(String name, 类<?>... parameterTypes)

             * Method[]     	getDeclaredMethods()
             * Method 	      getDeclaredMethod(String name, 类<?>... parameterTypes)
        4.获取类名
              *	 String getName()
     */

    public static void main(String[] args) throws Exception {


        //1.获取Person的Class对象
        Class personClass = Person.class;
        /*
         1.获取成员变量们
             * Field[] getFields()  -----获取所有public修饰的成员变量
             * Field[] getField(String name) -----获取指定的public修饰的成员变量

             * Field[] getDeclaredFields()
             * Field[] getDeclaredField(String name)
         */

        //1.Field[] getFields() 获取所有public修饰的成员变量
        Field[] fields = personClass.getFields();
        for (Field field : fields) {
            System.out.println(field);
        }
        System.out.println("-------------------");
        //2.Field[] getField(String name) -----获取指定的public修饰的成员变量
        Field a = personClass.getField("a");
        //获取成员变量a 的值
        Person p = new Person();
        Object value = a.get(p);
        System.out.println(value);
        //设置a的值
        a.set(p,"张三啊啊啊啊");
        System.out.println(p);

        System.out.println("============ ");
        System.out.println("获取所有的成员变量,不考虑修饰符");
        // Field[] getDeclaredFields():获取所有的成员变量,不考虑修饰符
        Field[] declaredFields = personClass.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            System.out.println(declaredField);
        }
        //Field[] getDeclaredField(String name)     //获取单个的成员变量,不考虑修饰符
        System.out.println("获取单个的成员变量,不考虑修饰符");
        Field d = personClass.getDeclaredField("d");
        //忽略访问权限修饰符的安全检查
        d.setAccessible(true);  //暴力反射
        Object value2 = d.get(p);
        System.out.println(value2);

    }
}

= = = = = = = = = = Person.java文件 = = = = = = = = = =

package cn.itcast.domain;

public class Person {
  private String name;
  private int age;

  public String a;
  public String DD;
  protected  String b;
  String c;
  private String  d;


  public Person(String name, int age) {
      this.name = name;
      this.age = age;
  }

  public Person() {
  }

  public String getName() {
      return name;
  }

  public void setName(String name) {
      this.name = name;
  }

  public int getAge() {
      return age;
  }

  public void setAge(int age) {
      this.age = age;
  }

  @Override
  public String toString() {
      return "Person{" +
              "name='" + name + '\'' +
              ", age=" + age +
              ", a='" + a + '\'' +
              ", DD='" + DD + '\'' +
              ", b='" + b + '\'' +
              ", c='" + c + '\'' +
              ", d='" + d + '\'' +
              '}';
  }
}

效果展示:

在这里插入图片描述

Constructor:构造方法

  • 创建对象:
    • T newInstance(Object… initargs)
    • 如果使用空参数构造方法创建对象,操作可以简化为:Class对象的newInstance方法
    • constructor.setAccessablite(true):暴力反射
示例代码:
public class ReflectDemo03 {
    /*
    Class对象功能:
        获取功能:
        1.获取成员变量们
             * Field[] getFields()
             * Field[] getField(String name)

             * Field[] getDeclaredFields()
             * Field[] getDeclaredField(String name)
        2.获取构造方法们
             * Constructor <?> [ ] 	       getConstructors ( )
             * Constructor<T>          getConstructor (类<?>. . . parameterTypes)

             * Constructor <?> [ ] 	 getDeclaredConstructors ( )
             * Constructor<T>          getDeclaredConstructor (类<?>. . . parameterTypes)
        3.获取成员方法们:
             * Method []     getMethods()
             * Method       getMethod(String name, 类<?>... parameterTypes)

             * Method[]     	getDeclaredMethods()
             * Method 	      getDeclaredMethod(String name, 类<?>... parameterTypes)
        4.获取类名
              *	 String getName()
     */

    public static void main(String[] args) throws Exception {

        //1.获取Person的Class对象
        Class personClass = Person.class;
        /*
          2.获取构造方法们
             * Constructor <?> [ ] 	       getConstructors ( )
             * Constructor<T>          getConstructor (类<?>. . . parameterTypes)

             * Constructor <?> [ ] 	 getDeclaredConstructors ( )
             * Constructor<T>          getDeclaredConstructor (类<?>. . . parameterTypes)
         */

        //1. Constructor <?> [ ] 	getConstructors ( )
            //获取字节码文件Person的类的构造器,使用有参构造
        Constructor constructors = personClass.getConstructor(String.class,int.class);
        System.out.println(constructors);
        //使用Contructor中的方法
        Object person = constructors.newInstance("张三", 15);
        System.out.println(person);
        System.out.println("============================");
        //使用无参构造
        Constructor constructors1 = personClass.getConstructor();
        System.out.println(constructors1);
        //使用Contructor1中的方法,创建对象
        Object person1 = constructors1.newInstance();
        System.out.println(person1);
        System.out.println("=============");
        //使用Class里面的方法创建对象
        Object o = personClass.newInstance();
        System.out.println(o);
    }
}

Method :方法对象

  • `执行方法:
    • Object invoke(Object obj, Object… args)
  • 获取方法名称:
    • `String getName:获取方法名。
示例代码:
public class ReflectDemo04 {
    /*
    Class对象功能:
        获取功能:
        1.获取成员变量们
             * Field[] getFields()
             * Field[] getField(String name)

             * Field[] getDeclaredFields()
             * Field[] getDeclaredField(String name)
        2.获取构造方法们
             * Constructor <?> [ ] 	       getConstructors ( )
             * Constructor<T>          getConstructor (类<?>. . . parameterTypes)

             * Constructor <?> [ ] 	 getDeclaredConstructors ( )
             * Constructor<T>          getDeclaredConstructor (类<?>. . . parameterTypes)
        3.获取成员方法们:
             * Method []     getMethods()
             * Method       getMethod(String name, 类<?>... parameterTypes)

             * Method[]     	getDeclaredMethods()
             * Method 	      getDeclaredMethod(String name, 类<?>... parameterTypes)
        4.获取类名
              *	 String getName()
     */

    public static void main(String[] args) throws Exception {

        //1.获取Person的Class对象
        Class personClass = Person.class;
            /*
                 * Method []     getMethods()
                 * Method       getMethod(String name, 类<?>... parameterTypes)

                 * Method[]     	getDeclaredMethods()
                 * Method 	      getDeclaredMethod(String name, 类<?>... parameterTypes)
             */

        //1.Method       getMethod(String name, 类<?>... parameterTypes)
        //获取指定名称的方法
        Method eat_method = personClass.getMethod("eat");
        Person person = new Person();
        //执行方法
        eat_method.invoke(person);

        System.out.println("===============");
        Method eat_method2 = personClass.getMethod("eat", String.class);
        //执行方法
        eat_method2.invoke(person,"好吃的");
        System.out.println("=====================");
        //查看所有的方法,包含了Object的方法还有类的方法;
        // Method []     getMethods()
        Method[] methods = personClass.getDeclaredMethods();

        for (Method method : methods) {
            //打印完整方法
            System.out.println(method);
            //获取方法名
            String name = method.getName();
            System.out.println(name);
//            method.setAccessible(true);//暴力反射
        }
        //获取类名:
        String className = personClass.getName();
        System.out.println(className);

    }
}

注解

  • 概念:说明程序的,给计算机看的。

  • 注释:用文字描述程序,给程序员看的,

  • 定义:注解(Annotation),也叫元数据。- 种代码级别的说明。它是JDK1. 5及以后版本引入的一个特性,与类、接口、枚举是在同-一个层次。它可以声明在包、类、字段、方法、局部变量、方法参数等的前面,用来对这些元素进行说明,注释。

  • 概念描述:

    • JDK 1.5 之后的新特性
    • 说明程序的
    • 使用注解:@注解名称
  • 作用分类:

  • @编写文档:通过代码里标识的注解生成文档[生成文档doc文档]
    ②代码分析:通过代码里标识的注解对代码进行分析[使用反射]
    ③编译检查:通过代码里标识的 注解让编译器能够实现基本的编译检查[override]

  • JDK中预定义的一些注解

    • @Override :检测被该注解标注的方法是否是继承自父类(接口)的

    • @Deprecated :该注解标注的内容,表示已过时

    • @SuppressWarnings :压制警告

      ​ * 一般传递参数all @SuppressWarnings(“all”)

  • 自定义注解

    • 格式:

      ​ * 元注解

      ​ * public @interface 注解名称{

      ​ 属性列表;(实际上是成员方法)

      }

    • 本质:注解本质上就是一个接口,该接口默认继承Annotation接口

      • public interface MyAnno extends java.lang.annotation.Annotation {
        }

      • 属性:接口中的抽象方法

        • 要求:
          • 1.属性的返回值类型有下列取值

            • 基本数据类型(八大基本类型= byte ,short,int ,long,float,double,char,boolean)--------四大引用:数组,类,接口,字符串
            • String
            • 枚举
            • 注解
            • 以上类型的数组
          • 2.定义了属性,在使用时需要给属性赋值

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

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

          • @Inherited:描述注解是否被子类继承

      • 在程序中使用(解析)注解

      在程序中使用(解析)注解

​ 1.获取注解定义的位置的对象,(class,Method,Field)

​ 2.获取指定的注解

​ getAnnotation(Class)

其实就是在内存中生成了一个该注释的子类实现对象
 /*
    public class ProImple  implements Pro{
        public String className(){
            return "cn.itcast.annotation.Demo1";
        }
        public String methodName(){
            return "show";
        }
*/

​ 3.调用注解中的抽象方法获取配置的属性值

小结

​ 1.以后大多数时候,我们会使用注解,为不是自定义注解

​ 2.注解给谁用?

​ 1.编译器

​ 2.给解析程序用

​ 3.注解不是程序的一部分,可以理解为注解就是一个标签

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱折磨键盘的大鹏

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值