1、引入
【1】历史
JDK5.0 新增 —— 注解(Annotation),也叫元数据。
【2】什么是注解?
注解其实就是代码里的特殊标记,这些标记可以在编译,类加载,运行时被读取,并执行相应的处理。通过使用注解,程序员可以在不改变原有逻辑的情况下,在源文件中嵌入一些补充信息。代码分析工具、开发工具和部署工具可以通过这些补充信息进行验证或者进行部署。
使用注解时要在其前面增加@符号,并把该注解当成一个修饰符使用。用于修饰它支持的程序元素。
【3】注解的重要性:
Annotation 可以像修饰符一样被使用,可用于修饰包,类,构造器,方法,成员变量,参数,局部变量的声明,这些信息被保存在Annotation的 "name=value" 对中。
在JavaSE中,注解的使用目的比较简单,例如标记过时的功能,忽略警告等。在JavaEE/ArIdroid中注解占据了更重要的角色,例如用来配置应用程序的任何切面,代替JavaEE旧版中所遗留的繁冗代码和XML配置等。
未来的开发模式都是基于注解的,JPA(java的持久化API)是基于注解的,Spring2.5以. E都是基于注解的,Hibernate3.x以后也是基于注解的,现在的Struts2有一部分也是基于注解的了,注解是一种趋势,一定程度上可以说 :框架=注解+反射+设计模式 。
2、注解的使用实例
【1】Junit的注解
@Test
@Before
@After
参考:208 - Junit_哆啦A梦的_梦的博客-CSDN博客
【2】文档相关的注解
对所写的函数加以注释:输入"/**",然后回车即可。
说明注释允许你在程序中嵌入关于程序的信息。你可以使用 javadoc 工具软件来生成信息,并输出到HTML文件中。
说明注释,使你更加方便的记录你的程序信息。
文档注解我们一般使用在文档注释中,配合javadoc工具
javadoc 工具软件识别以下标签:
其中注意:
Ø @param @return和@exception这三个标记都是只用于方法的。
Ø @param的格式要求: @param 形参名 形参类型 形参说明
Ø @return的格式要求: @return 返回值类型返回值说明,如果方法的返回值类型是void就不能写
Ø @exception的格式要求: @exception 异常类型异常说明
Ø @param和@exception可以并列多个
代码示例:
package test2_Annotation;
import jdk.internal.org.objectweb.asm.tree.VarInsnNode;
/**
* @Auther: zhoulz
* @Date: 2022-1-1
* @Description: 123
* @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;
}
}
}
IDEA中的javadoc使用
步骤:
其中,为了 防止乱码: -encoding UTF-8 -charset UTF-8
【3】JDK内置的3个注解
1)@Override: 限定重写父类方法,该注解只能用于方法;
2)@Deprecated: 用于表示所修饰的元素 (类、方法、构造器、属性等) 已过时;
通常是因为所修饰的结构危险或存在更好的选择。
3)@SuppressWarnings: 抑制编译器警告
记得传入 “unused” 参数。
代码示例:
父类:Person
package test3_Annotation_three;
/**
* @Auther: zhoulz
* @Date:
* @Description:
* @version: 1.0
*/
public class Person {
public void run(){
System.out.println("父类Person —— run()");
}
}
子类:Student
package test3_Annotation_three;
/**
* @Auther: zhoulz
* @Date:
* @Description:
* @version: 1.0
*/
public class Student extends Person {
//1、@Override的作用:限定重写的方法,只要重写方法有问题,
// 就有错误提示。
@Override
public void run(){ //run 错写为 ron等 就会报错 / 或直接报错
System.out.println("子类Student —— run()");
}
//2、在方法前加入@Deprecated,这个方法就会变成
// 一个废弃方法/过期方法/过时方法
@Deprecated
public void study(){
System.out.println("study!!!");
}
}
测试类:Test1
package test3_Annotation_three;
import java.util.ArrayList;
import java.util.Date;
/**
* @Auther: zhoulz
* @Date:
* @Description:
* @version: 1.0
*/
public class Test1 {
public static void main(String[] args) {
//类似于Date类中一些过时的方法
Date d = new Date();
System.out.println(d.getMonth());//显示为过时方法
new Student().study(); //显示为过时方法
//3、@SuppressWarnings:抑制编译器警告
// 记得传入“unused”参数
@SuppressWarnings("unused")
int age = 10; //正常情况下,age不使用会被警告/或为灰色
int num = 20;
System.out.println(num);//num 使用了就不会为灰色
//后面学习的集合
@SuppressWarnings({"unused","rwatypes"})
//unused — 抑制不使用的警告
//rwatypes — 抑制泛型的警告
ArrayList al = new ArrayList();
//Eclipse中会推荐使用泛型,如下:
ArrayList<String> al2 = new ArrayList<String>();
}
}
【4】实现替代配置文件功能的注解
在servlet3.0之前的配置:
<?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> |
在servlet3.0之后,使用注解替代配置文件:
package com.bjsxt.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() { } } |
3、自定义注解
【1】自定义注解使用很少,一般情况下都是用现成的注解;
【2】如何自定义注解:
发现定义的注解的声明使用的关键字:@interface,跟接口没有一点关系。
【3】注解的内部:
以@SuppressWarnings为例,发现内部:
这value是属性还是方法?
答案:看上去是无参数方法,实际上可以理解为一个成员变量,一个属性。
无参数方法名字 —— 成员变量的名字(这里为:value()),
无参数方法的返回值 —— 成员变量的类型(这里为:String[ ]),
这个参数叫 配置参数,即:String [ ] value() 。
无参数方法的类型:
基本数据类型(八种),String,枚举,注解类型,还可以是以上类型对应的数组。
PS:注意:如果只有一个成员变量的话,名字尽量叫value。
【4】使用注解:
(1)使用注解的话,如果你定义了配置参数(或者说成员变量),就必须给配置参数进行赋值操作;
(2)如果只有一个参数,并且这个参数的名字为value的话,那么 value= 可以省略不写;
(3)如果你给配置参数设置默认的值了,那么使用的时候可以无需传值;
示例代码:
(注:一个注解对应一个文件)
注解:MyAnnotaton
public @interface MyAnnotation {
String[] value();
}
注解2:MyAnnotaton2 —— 设置了默认的值
public @interface MyAnnotation2 {
String value() default "abc";
}
测试类:Person
package test4_Annotation_selfDefine;
/**
* @Auther: zhoulz
* @Date:
* @Description:
* @version: 1.0
*/
@MyAnnotation(value = {"abc","def","ghi"})
//赋值的方式?因为value是String类型的数组
//value可以省略不写
//@MyAnnotation({"abc","def","ghi"})
@MyAnnotation2 //可以不用赋值了
public class Person {
}
(4)一个注解的内部是可以不定义配置参数的。
public @interface MyAnnotation3 {
}
内部没有定义配置参数的注解 — 可以叫做标记,如之前学的@Override 。
内部定义配置参数的注解 — 叫做元数据
【5】注解的使用
现在只学习注解的大致技能点,具体怎么应用 ,后面慢慢学习。
(反射、junit、 .....)
4、元注解
参考:218 - 元注解_哆啦A梦的_梦的博客-CSDN博客