Java注解

介绍

注解(Annotation)也被称为元数据,用于修饰解释 包、类、方法、属性、构造器、局部变量和方法参数等数据信息。

和注释一样,注解不影响程序逻辑,但注解可以被编译或运行,相当于嵌入在代码中的补充信息,用来对这些元素进行说明。

使用Annotation时要在其前面增加@符号,并把该Annotation当成一个修饰符使用。用于修饰它支持的程序元素。

生成api文档相关注解:

/*****类文档注释中使用的注解*****/
@author:标明开发该类模块的作者,多个作者之间使用,分隔
@version:标明该类模块的版本
@see:参考转向,也就是相关主题
@since:从哪个版本开始增加的
/*****方法文档注释使用的注解*****/
@param:对方法中某参数的说明,如果没有参数就不能写。格式:@param 形参名 形参类型 形参说明
@return:对方法返回值的说明,如果方法的返回值类型是void就不能写。格式:@return 返回值类型 返回值说明
@exception:对方法可能抛出的异常进行说明,如果方法没有用throws显式抛出的异常就不能写其中。格式:@exception 异常类型 异常说明
// @param和@exception可以并列多个

作用分类:

①编写文档:通过代码里标识的注解生成文档(使用jdk工具javadoc生成doc文档)

②代码分析:通过代码里标识的注解对代码进行分析(使用反射)

③编译检查:通过代码里标识的注解让编译器能够实现基本的编译检查(基本注解如:@Override)

三个基本Annotation:

@Override:限定某个方法,是重写父类方法,该注解只能用于方法

@Deprecated:用于表示某个程序元素(类,方法等)已过时

@SuppressWarnings:抑制编译器警告

自定义注解

注解格式

@元注解
public @interface 注解名称 {
属性列表;
}

@interface表示是注解类,不是接口interface;是JDK1.5之后加入的。

注解本质

自定义一个注解:

public @interface MyAnnotation {
}

通过javap反编译我们可以看到,其实注解本质上就是一个接口,该接口默认继承Annotation接口

属性定义

注解本身就是一个接口,而接口中我们可以定义各种属性(抽象方法)。

属性的返回值类型有以下几种:

8种基本数据类型

String

枚举

注解

Class(类)

以上类型的数组

举个🌰:

public @interface MyAnnotation {
// "注解属性定义"
int number();
String name();
CityEnum cityEnum();
CityAnnotation cityAnnotation();
String[] cityArray();
}
enum CityEnum {
HANG_ZHOU("杭州"),
SHANG_HAI("上海"),
BEI_JING("北京"),
HA_ER_BIN("哈尔滨");
String name;
CityEnum(String name) {
this.name = name;
}
}
@interface CityAnnotation {
}

自定义注解使用🌰

/*
* 定义了属性,使用时需要给属性赋值
* 1.如果定义属性时,使用default关键字给属性默认初始化值,则使用注解时,可以不进行属性的赋值,没有初始化值则必须使用时赋值
* 2.如果只有一个属性需要赋值,并且属性的名称时 value,则'value='可以省略,直接定义值即可
* 3.数组赋值时,值使用 {} 包裹。如果数组中只有一个值,则可以省略 {}
* */
@MyAnnotation(number = 1, name = "hguo", cityEnum = CityEnum.HANG_ZHOU, cityAnnotation = @CityAnnotation, cityArray = {"666", "978"})
public class TestAnnotation {
}

如果定义属性时,使用default关键字给属性默认初始化值,则使用注解时,可以不进行属性的赋值,没有初始化值则必须使用时赋值

@MyAnnotation
public class TestAnnotation {
}
public @interface MyAnnotation {
// default给属性初始化赋值
int number() default 1;
}

如果只有一个属性需要赋值,并且属性的名称时 value,则'value='可以省略,直接定义值即可

@MyAnnotation("hangzhou")
public class TestAnnotation {
}
public @interface MyAnnotation {
// 属性名称为value
String value();
}

数组赋值时,值使用 '{ }' 包裹。如果数组中只有一个值,则可以省略 '{ }'

@MyAnnotation(name = "hangzhou") // 只有一个值可以省略{}
public class TestAnnotation {
}
public @interface MyAnnotation {
// 数组类型属性
String[] name();
}

元注解

用于描述注解的注解。

@Target

描述注解能够作用的位置范围,内部定义了ElementType类型数组属性。

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Target {
ElementType[] value();
}

ElementType常用取值:

TYPE:用于描述类、接口(包括注解类型)或enum

METHOD:用于描述方法

FIELD:用于描述成员变量(域)

CONSTRUCTOR:用于描述构造器

LOCAL_VARIABLE:用于描述局部变量

PACKAGE:用于描述包

PARAMETER:用于描述参数

@Retention

描述注解被保留的阶段。内部定义了RetentionPolicy类型属性。

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {
RetentionPolicy value();
}
@Retention(RetentionPolicy.SOURCE)

RetentionPolicy中包括以下三种:

RetentionPolicy.RUNTIME:当前被被描述的注解,会保留class字节码文件中,并被JVM读取到。也是常用的类型。只有声明为RUNTIME生命周期的注解,才能通过反射获取。

RetentionPolicy.CLASS:当前被被描述的注解,会保留class字节码文件中,但是不会被JVM读取到。默认值类型。

RetentionPolicy.SOURCE:当前被被描述的注解,不会保留class字节码文件中,更不会被JVM读取到

@Documented

被该注解修饰的Annotation将被javadoc工具提取成文档。默认情况下,javadoc是不包括注解的。

定义为@Documented的注解必须设置Retention值为RUNTIME。

@Inherited

描述注解是否被子类继承,具有继承性。(使用较少)例如:父类使用了自定义注解,且自定义注解中的元注解声明了@Inherited,子类也会继承父类使用的自定义注解。

🌰:

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface MyAnnotation {
String[] name();
}

posted @   Lz_蚂蚱  阅读(38)  评论(0编辑  收藏  举报
(评论功能已被禁用)
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起