注解用于修饰包、类、方法、属性、构造器、局部变量等数据信息,它可以用于创建文档,跟踪代码的依赖性,甚至执行基本编译时检查,和注释一样,注解不影响程序逻辑,但注解可以被编译或运行,相当于嵌入式在代码中的补充信息,另外可以在编译时选择代码里的注解是否只存在于源代码级,或者它也能在 class 文件或者运行中出现。
在 Java SE 中,注解的使用目的比较简单,例如:标记过时的功能,忽略警告等。在 Java EE 中注解占据了更重要的角色,例如:用来配置应用程序的任何切面,代替 Java EE 旧版中所遗留的冗余代码和 XML 配置等。
注解 (Annotation) 相当于一种标记,在程序中加入注解就等于为程序打上某种标记之后,javac
编译器、开发工具和其他程序可以通过反射来了解类及各种元素上有无何种标记,根据标记的不同执行对应的程序,标记可以加在包、类,属性、方法,方法参数以及局部变量上。
作用
:给程序带入参数
注解是JDK1.5的新特性:
JVM
看的,编译器或 JVM
可以根据注解来完成对应的功能以下几个常用操作中都使用到了注解:
@Author
和 @Version
@Override
元注解:Java
官方提供的注解,用来定义注解的注解,任何官方提供的非元注解的定义都使用到了元注解。
注解类型:类注解
作用:表示该注解用于什么地方,可能的值在枚举类 ElemenetType
中,包括:
枚举 | 说明 |
---|---|
ElemenetType.CONSTRUCTOR | 构造方法 |
ElemenetType.FIELD | 成员变量(包括 enum 实例) |
ElemenetType.LOCAL_VARIABLE | 局部变量 |
ElemenetType.METHOD | 成员方法 |
ElemenetType.PACKAGE | 包声明 |
ElemenetType.PARAMETER | 方法参数 |
ElemenetType.TYPE | 类,接口(包括注解类型)或enum声明 |
ElemenetType.ANNOTATION_TYPE | 注解类 |
ElemenetType.TYPE_PARAMETER | 类型参数 |
ElemenetType.TYPE_USE | 任意类型 (不包括class) |
查看 @Target
注解的定义,源码如下:
package java.lang.annotation;
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Target {
ElementType[] value();
}
枚举类 ElementTyper
的源码:
package java.lang.annotation;
public enum ElementType {
TYPE,
FIELD,
METHOD,
PARAMETER,
CONSTRUCTOR,
LOCAL_VARIABLE,
ANNOTATION_TYPE,
PACKAGE,
TYPE_PARAMETER,
TYPE_USE
}
注解类型:类注解
作用:用来识别注解的生命周期(有效范围),表示在什么级别保存该注解信息。可选的参数值在枚举类型 RetentionPolicy
中,包括:
枚举 | 说明 |
---|---|
RetentionPolicy.SOURCE | 注解只作用在源码阶段,生成的字节码文件中不存在 |
RetentionPolicy.CLASS | 注解作用在源码阶段,字节码文件阶段,运行阶段不存在,默认值 |
RetentionPolicy.RUNTIME | 注解作用在源码阶段,字节码文件阶段,运行阶段 |
查看 @Retention
注解的定义,源码如下:
package java.lang.annotation;
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {
RetentionPolicy value();
}
枚举类 RetentionPolicy
的源码:
package java.lang.annotation;
public enum RetentionPolicy {
SOURCE,
CLASS,
RUNTIME
}
注解类型:类注解
作用:将此注解包含在 javadoc
中 ,它代表着此注解会被 javadoc
工具提取成文档。在 doc
文档中的内容会因为此注解的信息内容不同而不同,相当与 @See
,@Param
等。
查看 @Documented
注解的定义,源码如下:
package java.lang.annotation;
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Documented {
}
注解类型:类注解
作用:允许子类继承父类中的注解。
查看 @Inherited
注解的定义,源码如下:
package java.lang.annotation;
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Inherited {
}
修饰符 @interface 注解名 {
属性
}
@interface
这个关键字的隐含意思是继承了 java.lang.annotation.Annotation
接口
java.lang.annotation.Annotation
的源码:
package java.lang.annotation;
public interface Annotation {
boolean equals(Object obj);
int hashCode();
String toString();
Class<? extends Annotation> annotationType();
}
同时我们还需要根据需要,添加对应的 元注解
,比如说我指向要该注解在方法上使用,就需要添加 @Target(ElementType.METHOD)
格式1:
数据类型 属性名(); //没有默认值的,需要后面赋值
格式2:
数据类型 属性名() default 默认值; //默认值可以改变
注解中能定义什么样的属性?
1、八种基本数据类型(不能使用包装类),如:byte、char、int、short、long、double、float、boolean
2、String类型、Class类型、枚举类型、注解类型
3、以上所有类型的一维数组
@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface Book {
String value();
double price() default 100;
String[] authros();
}
----------------------------------注意点----------------------------------
特殊属性 value:
value
,则在使用该注解时可以直接给该属性赋值,而不需要给出属性名。value
属性之外还有其他属性且只要有一个属性没有默认值,则在给属性赋值时,value
属性名也不能省略了。小结:如果注解中只有一个属性时,一般都会将该属性名命名为 value
。
使用注解时的注意事项:
,
隔开;如果注解中的属性有数组,那么如果数组只有一个元素值,那么 { }
不用写,反之需要写注解解析:使用 Java
技术获得注解上数据的过程则称为注解解析。
定义在 java.lang.Override
中,此注解只适用于修饰方法,表示一个方法声明打算重写超类中的另一个方法声明。
查看 @Override
注解的定义,源码如下:
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}
我们前面学习了 元注解
,就可以了解到该注解的一些基本信息,比如:@Target(ElementType.METHOD)
表示该注解只能标记在方法上,@Retention(RetentionPolicy.SOURCE)
注解只作用在源码阶段,生成的字节码文件中不存在,没有属性值等等。
一般子类或者实现类重写其超类的方法时,会在重写的方法上添加该注解,例如:
public class A extends B implements C {
private void funA() {
}
@Override
public void funB() {
}
@Override
public void funC() {
}
}
class B {
public void funB() {}
}
interface C {
void funC();
}
定义在 java.lang.Deprecated
中,此注解可以用于修饰方法、属性、类。表示不鼓励程序员使用这样的元素,通常是因为它很危险或者存在更好的选择。
查看 @Deprecated
注解的定义,源码如下:
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE})
public @interface Deprecated {
}
通常我们可以看到某些类中会存在这种注解,表示当前类、属性或者是方法已过时,不推荐使用,比如:Date 类中的一些方法。
定义在 java.lang.SuppressWarnings
中,用来抑制编译时的警告信息,该注解需要添加指定参数才能正常使用,比如:all
、unchecked
、deprecation
。
查看 @SuppressWarnings
注解的定义,源码如下:
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
@Retention(RetentionPolicy.SOURCE)
public @interface SuppressWarnings {
/**
* The set of warnings that are to be suppressed by the compiler in the
* annotated element. Duplicate names are permitted. The second and
* successive occurrences of a name are ignored. The presence of
* unrecognized warning names is not an error: Compilers must
* ignore any warning names they do not recognize. They are, however,
* free to emit a warning if an annotation contains an unrecognized
* warning name.
*
* The string {@code "unchecked"} is used to suppress
* unchecked warnings. Compiler vendors should document the
* additional warning names they support in conjunction with this
* annotation type. They are encouraged to cooperate to ensure
* that the same names work across multiple compilers.
* @return the set of warnings to be suppressed
*/
String[] value();
}
该注解的作用为抑制警告,根据 value
属性指定参数使用
关键字 | 用途 |
---|---|
all | 抑制所有警告 |
boxing | 抑制装箱、拆箱操作时候的警告 |
cast | 抑制映射相关的警告 |
dep-ann | 抑制启用注释的警告 |
deprecation | 抑制过期方法警告 |
fallthrough | 抑制确在switch中缺失breaks的警告 |
finally | 抑制finally模块没有返回的警告 |
hiding | 抑制相对于隐藏变量的局部变量的警告 |
incomplete-switch | 忽略没有完整的switch语句 |
nls | 忽略非nls格式的字符 |
null | 忽略对null的操作 |
rawtypes | 使用generics时忽略没有指定相应的类型 |
restriction | restriction |
serial | 忽略在serializable类中没有声明serialVersionUID变量 |
static-access | 抑制不正确的静态访问方式警告 |
synthetic-access | 抑制子类没有按最优方法访问内部类的警告 |
unchecked | 抑制没有进行类型检查操作的警告 |
unqualified-field-access | 抑制没有权限访问的域的警告 |
unused | 抑制没被使用过的代码的警告 |
不过最常用的还是这三种用法:
@SuppressWarnings("unchecked")
:抑制单类型的警告@SuppressWarnings("unchecked","rawtypes")
: 抑制多类型的警告@SuppressWarnings("all")
: 抑制所有类型的警告在很多地方都可以看到这个注解的存在,比如:ArrayList 的源码中
HashMap 的扩容方法中
作为有洁癖的开发人员,如果我们自己的写的某个类中出现了报警,但你知道它不会出错,可以添加该直接把 报黄的警报
给抑制下去。