您现在的位置是:首页 >技术杂谈 >面向对象(高级)-Annotation注解、单元测试的使用网站首页技术杂谈
面向对象(高级)-Annotation注解、单元测试的使用
注解(Annotation)
注解大纲
注解的使用
1.Annotation的理解
- 注解(Annotation)是从'JDK5.0'开始引入,以'@注解名'在代码中存在。
- Annotation可以像修饰符一样被使用,可用于修饰包、类、构造器、方法、成员变量、参数、局部变量的声明。
还可以添加一些参数值,这些信息被保存在Annotation的"name = value"对中。
- 注解可以在类编译、运行时进行加载,体现不同的功能。
2.注解的应用场景:
示例1:生成文档相关的注解
示例2:在编译时进行格式检查(JDK内置的三个基本注解)
示例3:跟踪代码依赖性,实现替代配置文件功能
3.JAVA基础涉及到的三个常用的注解
@Override:限定重写父类方法,该注解只能用于方法
@Deprecated:用于表示所修饰的元素(类,方法等)已过时。通常是因为所修饰的结构危险或存在更好的选择
@SuppressWarnings:抑制编译器警告 IDEA代码右边滚动条底下黄色的小横杠就是各种警告信息,如没使用这个变量,方法过时等,
如何取消小黄杠?
鼠标指针放在小黄杠上,点击右下角的More Actions...(更多操作...)——点击黄色小灯泡最右边的向右三角形,选择Suppress...小黄杠就没了
4.自定义注解
以@SuppressWarnings为参照,进行定义即可。
5.元注解的理解:
元注解:对现有的注解进行解释说明的注解。
讲4个元注解:
(1). @Target:用于描述注解的使用范围
- 可以通过枚举类型ElementType的10个常量对象来指定
- TYPE,METHOD,CONSTRUCTOR,PACKAGE......
(2). @Retention:用于描述注解的生命周期
- 可以通过枚举类型RetentionPolicy的3个常量对象来指定
- SOURCE(源代码)、CLASS(字节码)、RUNTIME(运行时)
- 唯有RUNTIME阶段才能被反射读取到。
(3). @Documented:表明这个注解应该被Javadoc工具记录。
(4). @Inherited:允许子类继承父类中的注解
拓展:元数据。
String name = "冰默";
String name是冰默的元数据
框架 = 注解 + 反射 + 设计模式
-
什么是注解
注解(Annotation)是从
JDK5.0
开始引入,以**@注解名
**在代码中存在。例如:
@Override //重写
@Deprecated //表示相应的一些结构过时了
@SuppressWarnings(value = "unchecked") //抑制编译器警告
Annotation可以像修饰符一样被使用,可用于修饰包、类、构造器、方法、成员变量、参数、局部变量的声明。还可以添加一些参数值,这些信息被保存在Annotation的"name = value"对中。
注解可以在类编译、运行时进行加载,体现不同的功能。
-
注解与注释
注解也可以看做是一种注释,通过使用Annotation,程序员可以在不改变原有逻辑的情况下,在源文件中嵌入一些补充信息。但是,注解,不同于单行注释和多行注释。
- 对于单行注释和多行注释是给程序员看的。
- 而注解是可以被编译器或其他程序读取的。程序还可以根据注解的不同,多出相应的处理。
-
注解的重要性
在JavaSE中,注解的使用目的比较简单,例如标记过时的功能,忽略警告等。在JavaEE/Android中注解占据了更重要的角色
,例如用来配置应用程序的任何切面,代替JavaEE旧版中所遗留的繁冗代码
和XML配置
等。
未来的开发模式都是基于注解的,JPA是基于注解的,Spring2.5以上都是基于注解的,Hibernate3.x以后也是基于注解的,Struts2有一部分也是基于注解的了。注解是一种趋势
,一定程度上可以说:框架 = 注解 + 反射 + 设计模式
。
常见的Annotation作用
示例1:生成文档相关的注解
@author 标明开发该类模块的作者,多个作者之间使用,分割
@version 标明该类模块的版本
@see 参考转向,也就是相关主题
@since 从哪个版本开始增加的
@param 对方法中某参数的说明,如果没有参数就不能写
@return 对方法返回值的说明,如果方法的返回值类型是void就不能写
@exception 对方法可能抛出的异常进行说明,如果方法没有用throws显示抛出的异常就不能写
示例2:在编译时进行格式检查(JDK内置的三个基本注解)
@Override
:限定重写父类方法,该注解只能用于方法
@Deprecated
:用于表示所修饰的元素(类,方法等)已过时。通常是因为所修饰的结构危险或存在更好的选择
@SuppressWarnings
:抑制编译器警告
示例3:跟踪代码依赖性,实现替代配置文件功能
- Servlet3.0提供了注解(annotation),使得不再需要在web.xml文件中进行Servlet的部署。
三个最基本的注解
-
@Override
- 用于检测被标记的方法为有效的重写方法,如果不是,则报编译错误!
- 只能标记在方法上。
- 它会被编译器程序读取。
-
@Deprecated
- 用于表示被标记的数据已经过时,不推荐使用。
- 可以用于修饰属性,方法,构造,类,包,局部变量,参数。
- 他会被编译器程序读取。
-
@SuppressWarnings
- 抑制编译警告。当我们不希望看到警告信息的时候,可以使用SuppressWarnings注解来抑制警告信息。
- 可以用于修饰类、属性、方法、构造、局部变量、参数。
- 他会被编译器程序读取。
- 可以指定的警告类型有(了解)
- all,抑制所有警告
- unchecked,抑制与未检查的作业相关的警告
- unused,抑制与未用的程式码及停用的程式码相关的警告
- deprecation,抑制与淘汰的相关警告
- nls,抑制与非nls字串文字相关的警告
- null,抑制与空值分析相关的警告
- rawtypes,抑制与使用raw类型相关的警告
- static -access,抑制与静态存取不正确相关的警告
- static- method,抑制与可能宣告为static的方法相关的警告
- super,抑制与置换方法相关但不含super呼叫的警告
- …
元注解
JDK1.5在java.long.annotation包定义了4个标准的meat-annotation类型,它们被用来提供对其他annotation类型作说明。
- **@Target:**用于描述注解的使用范围
- 可以通过枚举类型ElementType的10个常量对象来指定
- TYPE,METHOD,CONSTRUCTOR,PACKAGE…
- **@Retention:**用于描述注解的生命周期
- 可以通过枚举类型RetentionPolicy的3个常量对象来指定
- SOURCE(源代码)、CLASS(字节码)、RUNTIME(运行时)
唯有RUNTIME阶段才能被反射读取到
。
-
@Documented:表明这个注解应该被Javadoc工具记录。
-
@Inherited:允许子类继承父类中的注解
package oop.demo15_annotation;
import java.util.Date;
public class AnnotationTest {
public static void main(String[] args) {
//new Student().walk();
Person p1 = new Student();
p1.walk();//学生走路
Date date = new Date();
System.out.println(date);
Date date1 = new Date(2023,4,11);//这是一个过时的方法,所以这个Date中间有条删除线,不推荐用,但是可以使用
System.out.println(date1);//输出3923,这个过时的方法要减去1900,才能是2023
Person p2 = new Person();
@SuppressWarnings({"deprecation"}) Person p3 = new Person("小明");
System.out.println(p3);
@SuppressWarnings("unused") int num = 10;
}
}
@MyAnnotation(value = "class")
class Person{
String name;
int age;
@MyAnnotation()//没写,默认就是Hello
//无参构造器
public Person() {
}
//有参构造器
@Deprecated //有了Deprecated说明以下方法为过时,上面用到这个方法的时候,这个方法名就有删除线
public Person(String name) {
this.name = name;
}
public void eat(){
System.out.println("人干饭");
}
public void walk(){
System.out.println("人走路");
}
@Override
public String toString() {
return "Person{" +
"name='" + name + ''' +
", age=" + age +
'}';
}
}
class Student extends Person{
@Override//注意Override只能够用来修饰方法
public void eat() {
System.out.println("学生干饭");
}
@Override
public void walk(){
System.out.println("学生走路");
}
}
自定义注解:
package oop.demo15_annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
//自定义的注解
@MyAnnotation("自定义的注解")
@Target({TYPE,FIELD, METHOD,CONSTRUCTOR})//限制注解能注解的范围,比如TYPE,可以注解类,接口;CONSTRUCTOR可以注解构造器
@Retention(RetentionPolicy.SOURCE)//限制注解存在的生命周期,SOURCE(源代码中存在)、CLASS(字节码中存在)、RUNTIME(运行时也存在)
public @interface MyAnnotation {
String value() default "Hello";//后面跟个default "Hello",意思就是没写String value(),他就默认用Hello
}
上面测试类AnnotationTest输出:
JUnit单元测试
单元测试大纲
Junit单元测试的使用:
1.需要导入的jar包:
Junit-4.12.jar
hamcrest-core-1.3.jar
2.导入步骤:
见笔记图片步骤
3.创建单元测试类,进行测试
见代码
4.(重点关注)要想能正确的编写单元测试方法,需要满足:
1. 所在的类必须是public的,非抽象的,包含唯一的无参构造器。
2. @Test标记的方法本身必须是public,非抽象的,非静态的,void无返回值,()无参数的。
5.默认情况下,单元测试方法中使用Scanner失效。如何解决?
最上面找到Help——点击Edit Custom VM Options...
——在-javaagent:C:jetbrains-agent.jar下面加这一句-Deditable.java.test.console=true
然后重启idea就可以输入了。
6.以后写代码会经常写单元测试方法,大家可以将单元测试方法设置为一个模板
怎么设置模板:
File——Settings...(设置)——Editor——Live Templates——点右面的“ + ”——Template Group...(先自己定义个组)
——CustomDefine(用户自定义),OK——在建的组里面再点“ + ”——Live Template——在Abbreviation(希望通过什么可以调出来)中写test
——Description(说明)中写自动生成单元测试方法
——Template text:(模板长什么样子)中写
@Test
public void test$var1$(){ //var变亮
$var2$
}
最后在下面Define,我们希望在java相关的逻辑中使用,选中Java,OK
- 测试分类
黑盒测试
:不需要写代码,给输入值,看程序是否能够输出期望的值。
白盒测试
:需要写代码的。关注程序具体的执行流程。
- JUnit单元测试介绍
JUnit是由Erich Gamma和Kent Beck编写的一个测试框架(regression testing framework),供java开发人员编写单元测试之用。
JUnit测试是程序猿测试,即所谓白盒测试,因为程序员知道被测试时的软件如何(HOW),完成功能和完成什么样(What)的功能。
要使用JUnit,必须在项目的编译路径中引入JUnit的库
,即相关的.class文件组成的.jar包。jar就是一个压缩包,压缩包都是开发好的第三方(Oracle公司第一方,我们自己第二方,其他都是第三方)工具类,都是以.class文件形式存在的。
本地包(我也是网上搜索包名下载的)
- 引入本地JUnit.jar
(1)
(2)
(3)
(4)
(5)
(6)检查一下Modules——Dependencies下的包是不是Compile。
(7)查看
注: 其他模块底下没有导入用到的jar包,怎么能调用且使用@Test单元测试
新建模块
这个模块用来学习单元测试@test不在这个模块底下,怎么添加用起来
1.让导入的jar包让这个模块用起来就能用@Test单元测试
- File——Project Structure...——Modules——选中junit_test——Dependencies——点击右边“ + ”,Library...
- 选中JUnit-libs包-Add selected——把右边Test改成Compile——Apply——Ok
2.在有网的情况下:
- 点到报红@Test那一行,Alt+Enter
- 点击Add "JUnit4'to classpath,然后OK,他就开始有网下载了
package junit_test;
import org.junit.Test;
public class JUnitOutTest {
@Test
public void test(){
System.out.println("Hello");
}
}
编写和运行@Test单元测试方法
JUnit4版本,要求@Test标记的方法必须满足如下要求:
- 所在的类必须是public的,非抽象的,包含唯一的无参构造器。
- @Test标记的方法本身必须是public,非抽象的,非静态的,void无返回值,()无参数的。
package oop.demo15_annotation.juint;
import org.junit.Test;
import java.util.Scanner;
public class JunitTest { //单元测试类
public static void main(String[] args) {
JunitTest test = new JunitTest();
System.out.println(test.number);
test.method();
}
int number = 10;
//无参构造器
// public JunitTest() { //单元测试类只能有一个构造器且是无参构造器,默认就有无参构造,干脆单元测试类直接不写构造器
// }
@Test
public void test1(){ //单元测试方法
System.out.println("Hello");//Hello
}
//可以列很多个单元测试方法
@Test //这里只运行这一个模块底下的,不像main方法,如果运行,连上面的,下面的都会运行,或者要把其他的注释了,导入这个包用"@test"单元测试就行了
public void test2(){
System.out.println("hello2");//hello2
System.out.println(number);//10
method();//输出method()...
int num = showInfo("China");//China
System.out.println(num);//1
}
public void method(){
System.out.println("method()...");
}
//上面单元测试方法底下调用
public int showInfo(String info){
System.out.println(info);
return 1;
}
//默认情况下,单元测试方法中使用Scanner失效,不能输入,解决办法看单元测试大纲
@Test
public void test3(){
Scanner scanner = new Scanner(System.in);
System.out.println("请输入一个数值:");
int num = scanner.nextInt();
System.out.println(num);
}
//模板里面添加了自动生成单元测试方法,测试一下(怎么添加模板看大纲)
@Test
public void test4(){
System.out.println("Hello");
}
@Test
public void test5(){
System.out.println("hello,冰默");
}
}
添加模板:
怎么设置模板:
File——Settings…(设置)——Editor——Live Templates——点右面的“ + ”——Template Group…(先自己定义个组)
——CustomDefine(用户自定义),OK——在建的组里面再点“ + ”——Live Template
——在Abbreviation(希望通过什么可以调出来)中写test
——Description(说明)中写自动生成单元测试方法
——Template text:(模板长什么样子)中写
@Test
public void test
v
a
r
1
var1
var1(){ //var变亮
v
a
r
2
var2
var2
}
最后在下面Define,我们希望在java相关的逻辑中使用,选中Java,OK