注解的作用是用来简化代码或者帮助程序完成某些功能的一种指令
注解
doc注解—文档注解
javadoc注解—
/**
* @author : Gavin
* @date: 2021/8/24 - 08 - 24 - 14:44
* @Description: Doczhujie
* @version: 1.0 指定类的版本
*/
public class Personper {
private String name;
private int age;
/**
* @deprecated 构造方法
* @param name 姓名
* @param age 年龄
*
*/
public Personper(String name, int age) {
this.name = name;
this.age = age;
}
}
/**
* @author : Gavin
* @date: 2021/8/24 - 08 - 24 - 14:33
* @Description: Doczhujie
* @version: 1.0
*/
public class Student extends Personper {
private String name;
private int age;
/**
* @deprecated 这是get方法,用于获取学生姓名
* @return String
** */
public String getName() {
return name;
}
/**
* @deprecated 用于设置学生姓名
* @param name 学生姓名
*
*/
public void setName(String name) {
this.name = name;
}
/**
* @inheritDoc
*/
public Student(String name, int age) {
super(name, age);
}
/**
@deprecated 这是一个学习的方法---已过时
@param subject 学生学习的科目
@return String 返回学生学习的科目
* */
public String Study(String subject){
return subject;
}
/**
* @exception RuntimeException
* @exception IndexOutOfBoundsException
* @return int
*/
public int getAge(){
if(age>120){
throw new RuntimeException();
}
if (age<0){
throw new IndexOutOfBoundsException();
}
return age;
}
}
这是文档注释,我们在看源代码的时候经常也会看到文档注释,比如—
注解的格式@+javadoc相关关键字------以下是doc注解关键字
doc注解的作用是能够帮助程序员生成doc文档,另一个是能够帮助另一个程序员更高的理解自己写的代码;
上图为生成注解后的文档形式—
为了避免生成后的文档为乱码需要指定生成为utf-8格式;
自定义注解类
首先观看一下源码中的注解格式—
格式----@interface
格式------注解类中的内容—
可以有元素,也可以没有
自定义注解类----
public @interface Gavin {
String[]name();//参数1
int[]age();//参数2
}
public class GavinTest {
@Gavin(name={"李二狗","张三","王五"},age={16,28,19})
public void show(){
System.out.println("请开始你的表演");
}
}
由上述代码可以发现注解的参数的应用----
1,可以理解为把参数作为某个类型的数组(可变参数)
格式是 参数名={},如果是多个参数,之间用逗号隔开;
除此之外还可以指定参数的默认值
public @interface Gavin {
String[]name() default "李二狗";//参数1
int[]age() default 18;//参数2
}
可以通过反射来获得该类的方法,参数和注解等信息;
常用的注解-----
最常用的恐怕是 覆写时候用的f覆写的注解—Override
public class Gavinper extends GavinTest {
@Override
public void show(){
}
}
另一个是压制警告注解
@SuppressWarnings(“unused”)
还有一个常用的注解----过时的,或者废弃的
我们在使用某些方法是经常会看到某方法加了条横杠—
来看下加横杠方法色注解
在深入学习之后—spring boot, ibatis 等基本就是用的注解方式来完成的;
注解的注解------元注解
元注解又成为注解的注解-----即修饰注解的一种注解,其本质还是一种注解;
元注解的分类–
元注解分为 以下几种
@Retention
@Target
@Documented
@Inherited
一个一个拆开来看—
@Retention-------控制注解的生命周期
先从源代码中找到他的痕迹
可以看到该注解要传入一个参数
继续探究-----RetentionPolicy类
该类是一个枚举类,里面只有三个参数
SOURCE------
标记为@Retention(RetentionPolicy.SOURCE) 表示被修饰的注释将被编译器丢弃。
CLASS-----
标记为@Retention(RetentionPolicy.CLASS) 表示被修饰的注释将由编译器记录在类文件中 ,但在运行时不需要被VM保留,这是默认值 行为。
RUNTIME-------
标记为@Retention(RetentionPolicy.RUNTIME) 注释将由编译器和记录在类文件中在运行时由VM保留,因此它们可能被反射读取。 另参考-- java.lang.reflect.AnnotatedElement
这三种注释的特点-----
简单的说就是负责被修饰的注解的生命周期
RESOURCE—
负责在编译阶段,在源文件中有效(即源文件保留),编译器直接丢弃这种策略的注释,在.class文件中不会保留注解信息
CLASS—
在class文件中有效(即class保留),保留在.class文件中,但是当运行Java程序时,他就不会继续加载了,不会保留在内存中,JVM不会保留注解。如果注解没有加Retention元注解,那么相当于默认的注解就是这种状态。
最后一种—
RUNTIME-----
在运行时有效(即运行时保留),当运行 Java程序时,JVM会保留注释,加载在内存中了,那么程序可以通过反射获取该注释。
简单的总结一下,
RESOURCE 是不在类的字节码文件中,自然也不会在内存中;
CLASS 是在类的字节码文件中,但也不会加载到内存中;
RUNTIME是加载在字节码文件中,也会加载到内存中,因此通过反射要想获得类的信息,需要标记为RUNTIME
@TARGET-------控制注解的修饰范围
来看一以下自定义的注解可以修饰的范围-------
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface Gavin {
String[]name() default "李二狗";//参数1
int[]age() default 18;//参数2
}
@Gavin()//修饰类
public class Gavinper extends GavinTest {
@Gavin()//修饰属性
int num=0;
@Gavin()//修饰构造方法
public Gavinper() {
}
@Gavin()//修饰方法
public void show(){
}
}
如果想要定义一个注解,只能修饰类或者属性或者方法等,那么就需要Target
来指定该注解修饰的范围
参考源代码中的信息可以发现,Target需要传入一个数组参数,用于指定修饰的范围
ElementType为枚举类,
有如下信息------------------------------------------
TYPE--------修饰类
METHOD---------修饰方法
PARAMETER-------修饰参数
CONSTRUCTOR-------修饰构造方法
LOCAL_VARIABLE------修饰局部变量
ANNOTATION_TYPE,------修饰注解
PACKAGE,----修饰包
TYPE_PARAMETER,-----修饰类参数
TYPE_USE----修饰引用类型
举个例子—
当然也可以指定多个修饰范围,取合集;
@Target({ElementType.LOCAL_VARIABLE,ElementType.CONSTRUCTOR,ElementType.METHOD,ElementType.ANNOTATION_TYPE,ElementType.FIELD,ElementType.TYPE})
public @interface Gavin {
String[]name() default "李二狗";//参数1
int[]age() default 18;//参数2
}
@Gavin(name = {"李二狗", "张三", "王五"}, age = {16, 28, 19})
public class GavinTest {
@Gavin(name = {"李二狗", "张三", "王五"}, age = {16, 28, 19})
public void show() {
System.out.println("请开始你的表演");
}
public static void main(String[] args) {
new GavinTest().show();
@Gavin(name = {"李二狗", "张三", "王五"}, age = {16, 28, 19})
int num = 0;
}
}
@Documented-----该注解能导入到API文档中
用于指定被该元注解修饰的注解类将被javadoc工具提取成文档。默认情况下,javadoc是 不包括注解的,但是加上了这个注解生成的文档中就会带着注解了
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import javax.lang.model.element.Element;
@Documented
@Target(value={ElementType.FIELD,ElementType.PARAMETER,ElementType.TYPE_PARAMETER,ElementType.TYPE,ElementType.METHOD,ElementType.ANNOTATION_TYPE,ElementType.CONSTRUCTOR,ElementType.LOCAL_VARIABLE})
@Retention(RetentionPolicy.RUNTIME)
public @interface Gavin {
String[]name() default "李二狗";//参数1
int[]age() default 18;//参数2
}
在导出的API中可以发现-----
@Inherited------子类能够继承父类的注解
被它修饰的Annotation将具有继承性。如果某个类使用了被
@Inherited修饰的Annotation,则其子类将自动具有该注解。