JavaSE大神进阶篇(第八期):全网最详细最通俗易懂的Java中Junit注解知识点汇总
·
Junit单元测试
-
引入
-
没有Junit的情况下如何测试
-
没有使用Junit的缺点:
-
代码
package com.xxx.calculator; public class Calculator { //加法: public int add(int a, int b) { return a+b; } //减法: public int sub(int a, int b) { return a-b; } }public class Test { public static void main(String[] args) { //测试加法 Calculator cal = new Calculator(); int result = cal.add(10, 20); System.out.println(result); //测试减法 /* int result = cal.sub(30, 10); System.out.println(result); */ } }public class Test02 { public static void main(String[] args) { Calculator cal = new Calculator(); //测试减法: int result = cal.sub(30, 10); System.out.println(result); } }
-
-
Junit的使用
-
【1】一般测试和业务做一个分离,分离为不同的包
-
【2】测试类的名字
-
【3】测试方法的定义
-
【4】测试方法定义完以后,不能直接就独立运行了必须要在方法前加入一个注解:
-
【5】导入Junit的依赖的环境:

-
【6】代码:
package com.xxx.test; import com.xxx.calculator.Calculator; import org.junit.Test; public class CalculatorTest { //测试add方法 @Test public void testAdd() { System.out.println("测试add方法"); Calculator cal = new Calculator(); int result = cal.add(10, 30); System.out.println(result); } //测试sub方法 @Test public void testSub(){ System.out.println("测试sub方法"); Calculator cal = new Calculator(); int result = cal.sub(10, 30); System.out.println(result); } } -
【7】判定结果:
-
【8】即使出现绿色效果,也不意味着你的测试就通过了,因为代码中逻辑也可能出现问题,这种情况怎么解决呢?
package com.xxx.test; import com.xxx.calculator.Calculator; import org.junit.Assert; import org.junit.Test; public class CalculatorTest { //测试add方法 @Test public void testAdd(){ System.out.println("测试add方法"); Calculator cal = new Calculator(); int result = cal.add(10, 30); //System.out.println(result); --> 程序的运行结果可以不关注 //加入断言:预测一下结果,判断一下我预测的结果和 实际的结果是否一致: Assert.assertEquals(40, result); //第一个参数:预测结果 第二个参数:实际结果 } //测试sub方法 @Test public void testSub(){ System.out.println("测试sub方法"); Calculator cal = new Calculator(); int result = cal.sub(10, 30); System.out.println(result); } }
-
-
@Before与@After-
@Before: -
@After: -
代码:
package com.xxx.test; import com.xxx.calculator.Calculator; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; public class CalculatorTest { @Before public void init(){ System.out.println("方法执行开始了。。。"); } @After public void close(){ System.out.println("方法执行结束了。。。"); } //测试add方法 @Test public void testAdd(){ System.out.println("测试add方法"); Calculator cal = new Calculator(); int result = cal.add(10, 30); //System.out.println(result); --> 程序的运行结果可以不关注 //加入断言:预测一下结果,判断一下我预测的结果和 实际的结果是否一致: Assert.assertEquals(40, result); //第一个参数:预测结果 第二个参数:实际结果 } //测试sub方法 @Test public void testSub(){ System.out.println("测试sub方法"); Calculator cal = new Calculator(); int result = cal.sub(10, 30); System.out.println(result); } }
-
注解
-
引入
-
【1】历史:
-
【2】什么是注解?
-
【3】注解的重要性:
-
Annotation可以像修饰符一样被使用,可用于修饰包,类,构造器,方法,成员变量,参数,局部变量的声明,这些信息被保存在Annotation的"name=value"对中 -
在
JavaSE中,注解的使用目的比较简单,例如标记过时的功能,忽略警告等 -
在
JavaEE/ArIdroid中注解占据了更重要的角色,例如用来配置应用程序的任何切面,代替JavaEE旧版中所遗留的繁冗代码和XML配置等 -
未来的开发模式都是基于注解的,
JPA(java的持久化API)是基于注解的,Spring2.5以前都是基于注解的,Hibernate3.x以后也是基于注解的,现在的Struts2有一部分也是基于注解的了,注解是一种趋势,一定程度上可以说:框架 = 注解 + 反射 + 设计模式
-
-
-
注解的使用实例
-
Junit的注解
package com.xxx.test; import com.msb.calculator.Calculator; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; public class CalculatorTest { @Before public void init(){ System.out.println("方法执行开始了。。。"); } @After public void close(){ System.out.println("方法执行结束了。。。"); } @Test public void testAdd(){ System.out.println("测试add方法"); Calculator cal = new Calculator(); int result = cal.add(10, 30); Assert.assertEquals(40, result); //第一个参数:预测结果 第二个参数:实际结果 } } -
文档相关的注解
-
说明注释 允许你在程序中嵌入关于程序的信息, 你可以使用
javadoc工具软件来生成信息,并输出到HTML文件中 -
说明注释 使你更加方便的记录你的程序信息
-
文档注解 我们一般使用在文档注释中,配合
javadoc工具 -
javadoc工具软件识别以下标签:
-
代码
package com.xxx.anno; /** * @author : msb-zhaoss * @version : 1.0 */ public class Person { /** * 下面是eat方法,实现了 xxx 功能 * @param num1 就餐人数 * @param num2 点了几个菜 */ public void eat(int num1,int num2){} /** * @param age 年龄 * @return int * @exception RuntimeException 当年龄过大的时候 * @exception IndexOutOfBoundsException 当年龄过小的时候 * @see Student */ public int sleep(int age){ new Student(); if(age > 100){ throw new RuntimeException(); } if(age < 0){ throw new IndexOutOfBoundsException(); } return 10; } }


-
-
JDK内置的3个注解
public class Person { public void eat(){ System.out.println("父类eat.."); } }public class Student extends Person { /* @Override的作用:限定重写的方法,只要重写方法有问题,就有错误提示 */ @Override public void eat(){ System.out.println("子类eat.."); } }public class Student extends Person { /* @Override的作用:限定重写的方法,只要重写方法有问题,就有错误提示 */ @Override public void eat(){ System.out.println("子类eat.."); } /* 在方法前加入@Deprecated, 这个方法就会变成一个废弃方法 / 过期方法 / 过时方法 */ @Deprecated public void study(){ System.out.println("学习。。"); } }
public class Test02 { public static void main(String[] args) { @SuppressWarnings("unused") int age = 10; int num = 10; System.out.println(num); @SuppressWarnings({"unused","rwatypes"}) ArrayList al = new ArrayList(); } } -
实现替代配置文件功能的注解
package com.xxxx.servlet; import javax.servlet.*; import java.io.IOException; public class HelloServlet implements Servlet { @Override public void init(ServletConfig servletConfig) throws ServletException {} @Override public ServletConfig getServletConfig() { return null; } @Override public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException { System.out.println("service方法被调用了..."); } @Override public String getServletInfo() { return null; } @Override public void destroy() {} }<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns = "http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation = "http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <!--配置Servlet--> <!--配置Servlet的信息--> <servlet> <servlet-name>HelloServlet</servlet-name> <servlet-class>com.bjsxt.servlet.HelloServlet</servlet-class> </servlet> <!--配置Servlet的映射路径--> <servlet-mapping> <servlet-name>HelloServlet</servlet-name> <!--http://localhost:8080/01-hello-servlet/hello--> <url-pattern>hello</url-pattern> </servlet-mapping> </web-app>package com.xxxx.servlet; import javax.servlet.*; import java.io.IOException; @WebServlet("/hello") public class HelloServlet implements Servlet { @Override public void init(ServletConfig servletConfig) throws ServletException {} @Override public ServletConfig getServletConfig() { return null; } /** * 用于提供服务, 接收请求, 处理响应 * @param servletRequest * @param servletResponse * @throws ServletException * @throws IOException */ @Override public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException { System.out.println("service方法被调用了..."); } @Override public String getServletInfo() { return null; } @Override public void destroy() {} }
-
-
自定义注解
-
元注解
-
概述
-
Retention
-
概述
-
案例

-
反编译查看字节码文件:发现字节码文件中没有
MyAnnotation这个注解package com.xxx.anno03; public class Person { public Person() {} } -
案例
@Retention(RetentionPolicy.CLASS) public @interface MyAnnotation { String[] value(); }@MyAnnotation({"abc", "def", "hij"}) public class Person {} -
反编译看字节码文件,字节码文件中带有
MyAnnotation注解:package com.xxx.anno3; @MyAunotation({"abc", "def", "hij"}) public class Person { public Person(){} } -
RetentionPolicy.RUNTIME在运行时有效 (即运行时保留) , 当运行Java程序时,JVM会保留注释,加载在内存中了,那么程序可以通过反射获取该注释
-
-
Target
-
Documented(很少)
-
Inherited(极少)
-
枚举
-
引入
-
【1】数学:枚举法
-
【2】在java中,类的对象是有限个,确定的。这个类我们可以定义为枚举类
-
【3】自定义枚举类:(JDK1.5之前自定义枚举类)
package com.msb.enum01; public class Season { //属性: private final String seasonName; //季节名字 private final String seasonDesc; //季节描述 //利用构造器对属性进行赋值操作: //构造器私有化,外界不能调用这个构造器,只能Season内部自己调用 private Season(String seasonName, String seasonDesc) { this.seasonName = seasonName; this.seasonDesc = seasonDesc; } //提供枚举类的有限的 确定的对象 public static final Season SPRING = new Season("春天","春暖花开"); public static final Season SUMMER = new Season("夏天","烈日炎炎"); public static final Season AUTUMN = new Season("秋天","硕果累累"); public static final Season WINTER = new Season("冬天","冰天雪地"); //额外因素 public String getSeasonName() { return seasonName; } public String getSeasonDesc() { return seasonDesc; } //toString(); @Override public String toString() { return "Season{" + "seasonName='" + seasonName + '\'' + ", seasonDesc='" + seasonDesc + '\'' + '}'; } } -
测试类
public class TestSeason { public static void main(String[] args) { Season summer = Season.SUMMER; System.out.println(summer/*.toString()*/); System.out.println(summer.getSeasonName()); } }
-
-
JDK1.5之后使用enum关键字来创建枚举类
-
JDK1.5以后使用enum关键字创建枚举类

-
变为下面的枚举类
package com.xxx.enum02; public enum Season { //提供枚举类的有限的 确定的对象:---> enum枚举类要求对象(常量)必须放在最开始位置 //多个对象之间用`,`进行连接,最后一个对象后面用;结束 SPRING("春天","春暖花开"), SUMMER("夏天","烈日炎炎"), AUTUMN("秋天","硕果累累"), WINTER("冬天","冰天雪地"); //属性 private final String seasonName ; //季节名字 private final String seasonDesc ; //季节描述 //利用构造器对属性进行赋值操作 //构造器私有化,外界不能调用这个构造器,只能Season内部自己调用 private Season(String seasonName, String seasonDesc) { this.seasonName = seasonName; this.seasonDesc = seasonDesc; } //额外因素 public String getSeasonName() { return seasonName; } public String getSeasonDesc() { return seasonDesc; } //toString(); @Override public String toString() { return "Season{" + "seasonName='" + seasonName + '\'' + ", seasonDesc='" + seasonDesc + '\'' + '}'; } } -
使用枚举类
public class TestSeason { public static void main(String[] args) { Season winter = Season.WINTER; System.out.println(winter); //enum关键字对应的枚举类的上层父类是:java.lang.Enum //但是我们自定义的枚举类的上层父类:Object System.out.println(Season.class.getSuperclass().getName()); //java.lang.Enum } } -
在源码中经常看到别人定义的枚举类形态
public enum Season { SPRING, SUMMER, AUTUMN, WINTER; } -
案例
-
Thread中的枚举类:State
public enum State { /** * 线程的 NEW(新建)状态,对象已创建,但尚未调用 start() 方法 */ NEW, /** * 可运行线程的线程状态 * 处于 runnable 状态的线程正在 Java 虚拟机中执行 * 但它可能正在等待来自操作系统的其他资源 * 比如处理器(CPU) */ RUNNABLE, /** * 线程被阻塞并等待监视器锁的线程状态 * 处于 blocked 状态的线程正在等待一个监视器锁 * 以便进入一个 synchronized 同步块/方法 * 或者在调用 Object.wait() 之后,重新进入一个 synchronized 同步块/方法 */ BLOCKED, /** * 等待线程的线程状态 * 一个线程因调用以下方法之一而进入等待状态: * Object.wait() 不带超时 * Thread.join() 不带超时 * LockSupport.park() * 处于等待状态的线程正在等待另一个线程执行特定操作 * 例如,调了 Object.wait() 的线程在等别人调 notify() * 调了 Thread.join() 的线程在等目标线程终止 */ WAITING, /** * 具有指定等待时间的等待线程的线程状态 * 线程因调用以下带正等待时间参数的方法之一而进入计时等待状态: * Thread.sleep(毫秒) * Object.wait(毫秒) 带超时 * Thread.join(毫秒) 带超时 * LockSupport.parkNanos(纳秒) * LockSupport.parkUntil(截止时间) */ TIMED_WAITING, /** * 终止线程的线程状态 * 该线程已经完成执行 */ TERMINATED; }
-
-
-
Enum类的常用方法
-
代码展示
package com.xxx.enum03; public class TestSeason { public static void main(String[] args) { //用enum关键字创建的Season枚举类上面的父类是:java.lang.Enum //常用方法子类Season可以直接拿过来使用: //toString(); ---> 获取对象的名字 Season autumn = Season.AUTUMN; System.out.println(autumn/*.toString()*/); //AUTUMN System.out.println("--------------------"); //values:返回枚举类对象的数组 Season[] values = Season.values(); for(Season s:values){ System.out.println(s/*.toString()*/); } System.out.println("--------------------"); //valueOf:通过对象名字获取这个枚举对象 //注意:对象的名字必须传正确,否则抛出异常 Season autumn1 = Season.valueOf("AUTUMN"); System.out.println(autumn1); } }
-
-
枚举类实现接口
-
定义一个接口
public interface TestInterface { void show(); } -
枚举类实现接口,并且重写show方法
public enum Season implements TestInterface { SPRING, SUMMER, AUTUMN, WINTER; @Override public void show() { System.out.println("这是Season...."); } } -
测试类
public class Test { public static void main(String[] args) { Season autumn = Season.AUTUMN; autumn.show(); Season summer = Season.SUMMER; summer.show(); } } -
上面发现所有的枚举对象,调用这个show方法的时候走的都是同一个方法,结果都一样
-
但是现在我想要:不同的对象 调用的show方法也不同
package com.xxx.enum04; import java.sql.SQLOutput; public enum Season implements TestInterface { SPRING{ @Override public void show() { System.out.println("这是春天。。。"); } }, SUMMER{ @Override public void show() { ystem.out.println("这是夏天。。"); } }, AUTUMN{ @Override public void show() { System.out.println("这是秋天"); } }, WINTER{ @Override public void show() { System.out.println("这是冬天"); } }; /* @Override public void show() { System.out.println("这是Season...."); } */ } -
测试类
public class Test { public static void main(String[] args) { Season autumn = Season.AUTUMN; autumn.show(); Season summer = Season.SUMMER; summer.show(); } }
-
-
实际应用
-
代码展示
package com.xxx.enum05; public class Person { //属性 private int age; private String name; private Gender sex; public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Gender getSex() { return sex; } public void setSex(Gender sex) { this.sex = sex; } @Override public String toString() { return "Person{" + "age=" + age + ", name='" + name + '\'' + ", sex='" + sex + '\'' + '}'; } }public enum Gender { 男, 女; }public class Test { public static void main(String[] args) { Person p = new Person(); p.setAge(19); p.setName("lili"); p.setSex(Gender.男); //传入枚举类Gender的对象: --> 在入口处对参数进行了限制 System.out.println(p); } } -
还可以通过枚举结合switch处理:
public class Test02 { public static void main(String[] args) { Gender sex = Gender.男; //switch后面的()中可以传入枚举类型 //switch后面的():int,short,byte,char,String, 枚举 switch (sex){ case 女: System.out.println("是个女孩"); break; case 男: System.out.println("是个男孩"); break; } } }
-
更多推荐








所有评论(0)