- 浏览: 333561 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
孙艳霞111:
java.lang.IllegalStateException: Argument [RedirectAttributes] is of type Model -
llnyxxzj:
如果问题未解决可以看看http://blog.360chwl. ...
Caused by: org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bea -
u013810758:
楼主求帮助类 ReflectionUtils,Hibernat ...
BaseDao可以这样设计 -
rankx:
你好,楼主可否发一份 ReflectionUtils,Hibe ...
BaseDao可以这样设计
来源http://www.cnblogs.com/xd502djj/archive/2012/07/26/2610040.html
Java注解是附加在代码中的一些元信息,用于一些工具在编译、运行时进行解析和使用,起到说明、配置的功能。
注解不会也不能影响代码的实际逻辑,仅仅起到辅助性的作用。包含在 java.lang.annotation 包中。
1、元注解
元注解是指注解的注解。包括 @Retention @Target @Document @Inherited四种。
1.1、@Retention: 定义注解的保留策略
@Retention(RetentionPolicy.SOURCE) //注解仅存在于源码中,在class字节码文件中不包含
@Retention(RetentionPolicy.CLASS) // 默认的保留策略,注解会在class字节码文件中存在,但运行时无法获得,
@Retention(RetentionPolicy.RUNTIME) // 注解会在class字节码文件中存在,在运行时可以通过反射获取到
1.2、@Target:定义注解的作用目标
其定义的源码为:
1 @Documented
2 @Retention(RetentionPolicy.RUNTIME)
3 @Target(ElementType.ANNOTATION_TYPE)
4 public @interface Target {
5 ElementType[] value();
6 }
@Target(ElementType.TYPE) //接口、类、枚举、注解
@Target(ElementType.FIELD) //字段、枚举的常量
@Target(ElementType.METHOD) //方法
@Target(ElementType.PARAMETER) //方法参数
@Target(ElementType.CONSTRUCTOR) //构造函数
@Target(ElementType.LOCAL_VARIABLE)//局部变量
@Target(ElementType.ANNOTATION_TYPE)//注解
@Target(ElementType.PACKAGE) ///包
由以上的源码可以知道,他的elementType 可以有多个,一个注解可以为类的,方法的,字段的等等
1.3、@Document:说明该注解将被包含在javadoc中
1.4、@Inherited:说明子类可以继承父类中的该注解
2、java 注解的自定义
下面是自定义注解的一个例子
@Documented
@Target({ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Yts {
public enum YtsType{util,entity,service,model};
public YtsType classType() default YtsType.util;
}
1 @Documented
2 @Retention(RetentionPolicy.RUNTIME)
3 @Target(ElementType.METHOD)
4 @Inherited
5 public @interface HelloWorld {
6 public String name()default "";
7 }
@Retention(RetentionPolicy.RUNTIME)
定义的这个注解是注解会在class字节码文件中存在,在运行时可以通过反射获取到。
@Target({ElementType.TYPE,ElementType.METHOD})
因此这个注解可以是类注解,也可以是方法的注解
这样一个注解就自定义好了,当然注解里面的成员可以为基本的数据类型,也可以为数据,Object等等
3 注解是定义好了,那么怎么来得到,解析注解呢?
java的反射机制可以帮助,得到注解,代码如下:
1 public class ParseAnnotation {
2
3 public void parseMethod(Class clazz) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException, SecurityException, NoSuchMethodException, InstantiationException{
4 Object obj = clazz.getConstructor(new Class[]{}).newInstance(new Object[]{});
5 for(Method method : clazz.getDeclaredMethods()){
6 HelloWorld say = method.getAnnotation(HelloWorld.class);
7 String name = "";
8 if(say != null){
9 name = say.name();
10 method.invoke(obj, name);
11 }
12 Yts yts = (Yts)method.getAnnotation(Yts.class);
13 if(yts != null){
14 if(YtsType.util.equals(yts.classType())){
15 System.out.println("this is a util method");
16 }else{
17 System.out.println("this is a other method");
18 }
19 }
20 }
21 }
22 @SuppressWarnings("unchecked")
23 public void parseType(Class clazz) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException{
24 Yts yts = (Yts) clazz.getAnnotation(Yts.class);
25 if(yts != null){
26 if(YtsType.util.equals(yts.classType())){
27 System.out.println("this is a util class");
28 }else{
29 System.out.println("this is a other class");
30 }
31 }
32 }
33
34 }
前一个方法是解析得到方法注解的,后一个方法是得到类注解的
以下是测试方法类
1 @Yts(classType =YtsType.util)
2 public class SayHell {
3
4 @HelloWorld(name = " 小明 ")
5 @Yts
6 public void sayHello(String name){
7 if(name == null || name.equals("")){
8 System.out.println("hello world!");
9 }else{
10 System.out.println(name + "say hello world!");
11 }
12 }
13 }
1 public static void main(String[] args) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException, SecurityException, NoSuchMethodException, InstantiationException {
2 ParseAnnotation parse = new ParseAnnotation();
3 parse.parseMethod(SayHell.class);
4 parse.parseType(SayHell.class);
5 }
http://blog.csdn.net/yixiaogang109/article/details/7328466
1、Annotation的工作原理:
JDK5.0中提供了注解的功能,允许开发者定义和使用自己的注解类型。该功能由一个定义注解类型的语法和描述一个注解声明的语法,读取注解的API,一个使用注解修饰的class文件和一个注解处理工具组成。
Annotation并不直接影响代码的语义,但是他可以被看做是程序的工具或者类库。它会反过来对正在运行的程序语义有所影响。
Annotation可以冲源文件、class文件或者在运行时通过反射机制多种方式被读取。
2、@Override注解:
java.lang
注释类型 Override
@Target(value=METHOD)
@Retention(value=SOURCE)
public @interface Override
表示一个方法声明打算重写超类中的另一个方法声明。如果方法利用此注释类型进行注解但没有重写超类方法,则编译器会生成一条错误消息。
@Override注解表示子类要重写父类的对应方法。
Override是一个Marker annotation,用于标识的Annotation,Annotation名称本身表示了要给工具程序的信息。
下面是一个使用@Override注解的例子:
class A {
private String id;
A(String id){
this.id = id;
}
@Override
public String toString() {
return id;
}
}
3、@Deprecated注解:
java.lang
注释类型 Deprecated
@Documented
@Retention(value=RUNTIME)
public @interface Deprecated
用 @Deprecated 注释的程序元素,不鼓励程序员使用这样的元素,通常是因为它很危险或存在更好的选择。在使用不被赞成的程序元素或在不被赞成的代码中执行重写时,编译器会发出警告。
@Deprecated注解表示方法是不被建议使用的。
Deprecated是一个Marker annotation。
下面是一个使用@Deprecated注解的例子:
class A {
private String id;
A(String id){
this.id = id;
}
@Deprecated
public void execute(){
System.out.println(id);
}
public static void main(String[] args) {
A a = new A("a123");
a.execute();
}
}
4、@SuppressWarnings注解:
java.lang
注释类型 SuppressWarnings
@Target(value={TYPE,FIELD,METHOD,PARAMETER,CONSTRUCTOR,LOCAL_VARIABLE})
@Retention(value=SOURCE)
public @interface SuppressWarnings
指示应该在注释元素(以及包含在该注释元素中的所有程序元素)中取消显示指定的编译器警告。注意,在给定元素中取消显示的警告集是所有包含元素中取消显示的警告的超集。例如,如果注释一个类来取消显示某个警告,同时注释一个方法来取消显示另一个警告,那么将在此方法中同时取消显示这两个警告。
根据风格不同,程序员应该始终在最里层的嵌套元素上使用此注释,在那里使用才有效。如果要在特定的方法中取消显示某个警告,则应该注释该方法而不是注释它的类。
@SuppressWarnings注解表示抑制警告。
下面是一个使用@SuppressWarnings注解的例子:
@SuppressWarnings("unchecked")
public static void main(String[] args) {
List list = new ArrayList();
list.add("abc");
}
5、自定义注解:
使用@interface自定义注解时,自动继承了java.lang.annotation.Annotation接口,由编译程序自动完成其他细节。在定义注解时,不能继承其他的注解或接口。
自定义最简单的注解:
public @interface MyAnnotation {
}
使用自定义注解:
public class AnnotationTest2 {
@MyAnnotation
public void execute(){
System.out.println("method");
}
}
5.1、添加变量:
public @interface MyAnnotation {
String value1();
}
使用自定义注解:
public class AnnotationTest2 {
@MyAnnotation(value1="abc")
public void execute(){
System.out.println("method");
}
}
当注解中使用的属性名为value时,对其赋值时可以不指定属性的名称而直接写上属性值接口;除了value意外的变量名都需要使用name=value的方式赋值。
5.2、添加默认值:
public @interface MyAnnotation {
String value1() default "abc";
}
5.3、多变量使用枚举:
public @interface MyAnnotation {
String value1() default "abc";
MyEnum value2() default MyEnum.Sunny;
}
enum MyEnum{
Sunny,Rainy
}
使用自定义注解:
public class AnnotationTest2 {
@MyAnnotation(value1="a", value2=MyEnum.Sunny)
public void execute(){
System.out.println("method");
}
}
5.4、数组变量:
public @interface MyAnnotation {
String[] value1() default "abc";
}
使用自定义注解:
public class AnnotationTest2 {
@MyAnnotation(value1={"a","b"})
public void execute(){
System.out.println("method");
}
}
6、设置注解的作用范围:
@Documented
@Retention(value=RUNTIME)
@Target(value=ANNOTATION_TYPE)
public @interface Retention
指示注释类型的注释要保留多久。如果注释类型声明中不存在 Retention 注释,则保留策略默认为 RetentionPolicy.CLASS。
只有元注释类型直接用于注释时,Target 元注释才有效。如果元注释类型用作另一种注释类型的成员,则无效。
public enum RetentionPolicy
extends Enum<RetentionPolicy>
注释保留策略。此枚举类型的常量描述保留注释的不同策略。它们与 Retention 元注释类型一起使用,以指定保留多长的注释。
CLASS
编译器将把注释记录在类文件中,但在运行时 VM 不需要保留注释。
RUNTIME
编译器将把注释记录在类文件中,在运行时 VM 将保留注释,因此可以反射性地读取。
SOURCE
编译器要丢弃的注释。
@Retention注解可以在定义注解时为编译程序提供注解的保留策略。
属于CLASS保留策略的注解有@SuppressWarnings,该注解信息不会存储于.class文件。
6.1、在自定义注解中的使用例子:
@Retention(RetentionPolicy.CLASS)
public @interface MyAnnotation {
String[] value1() default "abc";
}
7、使用反射读取RUNTIME保留策略的Annotation信息的例子:
java.lang.reflect
接口 AnnotatedElement
所有已知实现类:
AccessibleObject, Class, Constructor, Field, Method, Package
表示目前正在此 VM 中运行的程序的一个已注释元素。该接口允许反射性地读取注释。由此接口中的方法返回的所有注释都是不可变并且可序列化的。调用者可以修改已赋值数组枚举成员的访问器返回的数组;这不会对其他调用者返回的数组产生任何影响。
如果此接口中的方法返回的注释(直接或间接地)包含一个已赋值的 Class 成员,该成员引用了一个在此 VM 中不可访问的类,则试图通过在返回的注释上调用相关的类返回的方法来读取该类,将导致一个 TypeNotPresentException。
isAnnotationPresent
boolean isAnnotationPresent(Class<? extends Annotation> annotationClass)
如果指定类型的注释存在于此元素上,则返回 true,否则返回 false。此方法主要是为了便于访问标记注释而设计的。
参数:
annotationClass - 对应于注释类型的 Class 对象
返回:
如果指定注释类型的注释存在于此对象上,则返回 true,否则返回 false
抛出:
NullPointerException - 如果给定的注释类为 null
从以下版本开始:
1.5
getAnnotation
<T extends Annotation> T getAnnotation(Class<T> annotationClass)
如果存在该元素的指定类型的注释,则返回这些注释,否则返回 null。
参数:
annotationClass - 对应于注释类型的 Class 对象
返回:
如果该元素的指定注释类型的注释存在于此对象上,则返回这些注释,否则返回 null
抛出:
NullPointerException - 如果给定的注释类为 null
从以下版本开始:
1.5
getAnnotations
Annotation[] getAnnotations()
返回此元素上存在的所有注释。(如果此元素没有注释,则返回长度为零的数组。)该方法的调用者可以随意修改返回的数组;这不会对其他调用者返回的数组产生任何影响。
返回:
此元素上存在的所有注释
从以下版本开始:
1.5
getDeclaredAnnotations
Annotation[] getDeclaredAnnotations()
返回直接存在于此元素上的所有注释。与此接口中的其他方法不同,该方法将忽略继承的注释。(如果没有注释直接存在于此元素上,则返回长度为零的一个数组。)该方法的调用者可以随意修改返回的数组;这不会对其他调用者返回的数组产生任何影响。
返回:
直接存在于此元素上的所有注释
从以下版本开始:
1.5
下面是使用反射读取RUNTIME保留策略的Annotation信息的例子:
自定义注解:
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
String[] value1() default "abc";
}
使用自定义注解:
public class AnnotationTest2 {
@MyAnnotation(value1={"a","b"})
@Deprecated
public void execute(){
System.out.println("method");
}
}
读取注解中的信息:
public static void main(String[] args) throws SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException {
AnnotationTest2 annotationTest2 = new AnnotationTest2();
//获取AnnotationTest2的Class实例
Class<AnnotationTest2> c = AnnotationTest2.class;
//获取需要处理的方法Method实例
Method method = c.getMethod("execute", new Class[]{});
//判断该方法是否包含MyAnnotation注解
if(method.isAnnotationPresent(MyAnnotation.class)){
//获取该方法的MyAnnotation注解实例
MyAnnotation myAnnotation = method.getAnnotation(MyAnnotation.class);
//执行该方法
method.invoke(annotationTest2, new Object[]{});
//获取myAnnotation
String[] value1 = myAnnotation.value1();
System.out.println(value1[0]);
}
//获取方法上的所有注解
Annotation[] annotations = method.getAnnotations();
for(Annotation annotation : annotations){
System.out.println(annotation);
}
}
8、限定注解的使用:
限定注解使用@Target。
@Documented
@Retention(value=RUNTIME)
@Target(value=ANNOTATION_TYPE)
public @interface Target
指示注释类型所适用的程序元素的种类。如果注释类型声明中不存在 Target 元注释,则声明的类型可以用在任一程序元素上。如果存在这样的元注释,则编译器强制实施指定的使用限制。 例如,此元注释指示该声明类型是其自身,即元注释类型。它只能用在注释类型声明上:
@Target(ElementType.ANNOTATION_TYPE)
public @interface MetaAnnotationType {
...
}
此元注释指示该声明类型只可作为复杂注释类型声明中的成员类型使用。它不能直接用于注释:
@Target({})
public @interface MemberType {
...
}
这是一个编译时错误,它表明一个 ElementType 常量在 Target 注释中出现了不只一次。例如,以下元注释是非法的:
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.FIELD})
public @interface Bogus {
...
}
public enum ElementType
extends Enum<ElementType>
程序元素类型。此枚举类型的常量提供了 Java 程序中声明的元素的简单分类。
这些常量与 Target 元注释类型一起使用,以指定在什么情况下使用注释类型是合法的。
ANNOTATION_TYPE
注释类型声明
CONSTRUCTOR
构造方法声明
FIELD
字段声明(包括枚举常量)
LOCAL_VARIABLE
局部变量声明
METHOD
方法声明
PACKAGE
包声明
PARAMETER
参数声明
TYPE
类、接口(包括注释类型)或枚举声明
注解的使用限定的例子:
@Target(ElementType.METHOD)
public @interface MyAnnotation {
String[] value1() default "abc";
}
9、在帮助文档中加入注解:
要想在制作JavaDoc文件的同时将注解信息加入到API文件中,可以使用java.lang.annotation.Documented。
在自定义注解中声明构建注解文档:
@Documented
public @interface MyAnnotation {
String[] value1() default "abc";
}
使用自定义注解:
public class AnnotationTest2 {
@MyAnnotation(value1={"a","b"})
public void execute(){
System.out.println("method");
}
}
10、在注解中使用继承:
默认情况下注解并不会被继承到子类中,可以在自定义注解时加上java.lang.annotation.Inherited注解声明使用继承。
@Documented
@Retention(value=RUNTIME)
@Target(value=ANNOTATION_TYPE)
public @interface Inherited
指示注释类型被自动继承。如果在注释类型声明中存在 Inherited 元注释,并且用户在某一类声明中查询该注释类型,同时该类声明中没有此类型的注释,则将在该类的超类中自动查询该注释类型。此过程会重复进行,直到找到此类型的注释或到达了该类层次结构的顶层 (Object) 为止。如果没有超类具有该类型的注释,则查询将指示当前类没有这样的注释。
注意,如果使用注释类型注释类以外的任何事物,此元注释类型都是无效的。还要注意,此元注释仅促成从超类继承注释;对已实现接口的注释无效。
除了文章中有特别说明,均为IT宅原创文章,转载请以链接形式注明出处。
本文链接:http://www.itzhai.com/java-based-notebook-annotation-annotation-introduction-and-use-custom-annotations.html
Java注解是附加在代码中的一些元信息,用于一些工具在编译、运行时进行解析和使用,起到说明、配置的功能。
注解不会也不能影响代码的实际逻辑,仅仅起到辅助性的作用。包含在 java.lang.annotation 包中。
1、元注解
元注解是指注解的注解。包括 @Retention @Target @Document @Inherited四种。
1.1、@Retention: 定义注解的保留策略
@Retention(RetentionPolicy.SOURCE) //注解仅存在于源码中,在class字节码文件中不包含
@Retention(RetentionPolicy.CLASS) // 默认的保留策略,注解会在class字节码文件中存在,但运行时无法获得,
@Retention(RetentionPolicy.RUNTIME) // 注解会在class字节码文件中存在,在运行时可以通过反射获取到
1.2、@Target:定义注解的作用目标
其定义的源码为:
1 @Documented
2 @Retention(RetentionPolicy.RUNTIME)
3 @Target(ElementType.ANNOTATION_TYPE)
4 public @interface Target {
5 ElementType[] value();
6 }
@Target(ElementType.TYPE) //接口、类、枚举、注解
@Target(ElementType.FIELD) //字段、枚举的常量
@Target(ElementType.METHOD) //方法
@Target(ElementType.PARAMETER) //方法参数
@Target(ElementType.CONSTRUCTOR) //构造函数
@Target(ElementType.LOCAL_VARIABLE)//局部变量
@Target(ElementType.ANNOTATION_TYPE)//注解
@Target(ElementType.PACKAGE) ///包
由以上的源码可以知道,他的elementType 可以有多个,一个注解可以为类的,方法的,字段的等等
1.3、@Document:说明该注解将被包含在javadoc中
1.4、@Inherited:说明子类可以继承父类中的该注解
2、java 注解的自定义
下面是自定义注解的一个例子
@Documented
@Target({ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Yts {
public enum YtsType{util,entity,service,model};
public YtsType classType() default YtsType.util;
}
1 @Documented
2 @Retention(RetentionPolicy.RUNTIME)
3 @Target(ElementType.METHOD)
4 @Inherited
5 public @interface HelloWorld {
6 public String name()default "";
7 }
@Retention(RetentionPolicy.RUNTIME)
定义的这个注解是注解会在class字节码文件中存在,在运行时可以通过反射获取到。
@Target({ElementType.TYPE,ElementType.METHOD})
因此这个注解可以是类注解,也可以是方法的注解
这样一个注解就自定义好了,当然注解里面的成员可以为基本的数据类型,也可以为数据,Object等等
3 注解是定义好了,那么怎么来得到,解析注解呢?
java的反射机制可以帮助,得到注解,代码如下:
1 public class ParseAnnotation {
2
3 public void parseMethod(Class clazz) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException, SecurityException, NoSuchMethodException, InstantiationException{
4 Object obj = clazz.getConstructor(new Class[]{}).newInstance(new Object[]{});
5 for(Method method : clazz.getDeclaredMethods()){
6 HelloWorld say = method.getAnnotation(HelloWorld.class);
7 String name = "";
8 if(say != null){
9 name = say.name();
10 method.invoke(obj, name);
11 }
12 Yts yts = (Yts)method.getAnnotation(Yts.class);
13 if(yts != null){
14 if(YtsType.util.equals(yts.classType())){
15 System.out.println("this is a util method");
16 }else{
17 System.out.println("this is a other method");
18 }
19 }
20 }
21 }
22 @SuppressWarnings("unchecked")
23 public void parseType(Class clazz) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException{
24 Yts yts = (Yts) clazz.getAnnotation(Yts.class);
25 if(yts != null){
26 if(YtsType.util.equals(yts.classType())){
27 System.out.println("this is a util class");
28 }else{
29 System.out.println("this is a other class");
30 }
31 }
32 }
33
34 }
前一个方法是解析得到方法注解的,后一个方法是得到类注解的
以下是测试方法类
1 @Yts(classType =YtsType.util)
2 public class SayHell {
3
4 @HelloWorld(name = " 小明 ")
5 @Yts
6 public void sayHello(String name){
7 if(name == null || name.equals("")){
8 System.out.println("hello world!");
9 }else{
10 System.out.println(name + "say hello world!");
11 }
12 }
13 }
1 public static void main(String[] args) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException, SecurityException, NoSuchMethodException, InstantiationException {
2 ParseAnnotation parse = new ParseAnnotation();
3 parse.parseMethod(SayHell.class);
4 parse.parseType(SayHell.class);
5 }
http://blog.csdn.net/yixiaogang109/article/details/7328466
1、Annotation的工作原理:
JDK5.0中提供了注解的功能,允许开发者定义和使用自己的注解类型。该功能由一个定义注解类型的语法和描述一个注解声明的语法,读取注解的API,一个使用注解修饰的class文件和一个注解处理工具组成。
Annotation并不直接影响代码的语义,但是他可以被看做是程序的工具或者类库。它会反过来对正在运行的程序语义有所影响。
Annotation可以冲源文件、class文件或者在运行时通过反射机制多种方式被读取。
2、@Override注解:
java.lang
注释类型 Override
@Target(value=METHOD)
@Retention(value=SOURCE)
public @interface Override
表示一个方法声明打算重写超类中的另一个方法声明。如果方法利用此注释类型进行注解但没有重写超类方法,则编译器会生成一条错误消息。
@Override注解表示子类要重写父类的对应方法。
Override是一个Marker annotation,用于标识的Annotation,Annotation名称本身表示了要给工具程序的信息。
下面是一个使用@Override注解的例子:
class A {
private String id;
A(String id){
this.id = id;
}
@Override
public String toString() {
return id;
}
}
3、@Deprecated注解:
java.lang
注释类型 Deprecated
@Documented
@Retention(value=RUNTIME)
public @interface Deprecated
用 @Deprecated 注释的程序元素,不鼓励程序员使用这样的元素,通常是因为它很危险或存在更好的选择。在使用不被赞成的程序元素或在不被赞成的代码中执行重写时,编译器会发出警告。
@Deprecated注解表示方法是不被建议使用的。
Deprecated是一个Marker annotation。
下面是一个使用@Deprecated注解的例子:
class A {
private String id;
A(String id){
this.id = id;
}
@Deprecated
public void execute(){
System.out.println(id);
}
public static void main(String[] args) {
A a = new A("a123");
a.execute();
}
}
4、@SuppressWarnings注解:
java.lang
注释类型 SuppressWarnings
@Target(value={TYPE,FIELD,METHOD,PARAMETER,CONSTRUCTOR,LOCAL_VARIABLE})
@Retention(value=SOURCE)
public @interface SuppressWarnings
指示应该在注释元素(以及包含在该注释元素中的所有程序元素)中取消显示指定的编译器警告。注意,在给定元素中取消显示的警告集是所有包含元素中取消显示的警告的超集。例如,如果注释一个类来取消显示某个警告,同时注释一个方法来取消显示另一个警告,那么将在此方法中同时取消显示这两个警告。
根据风格不同,程序员应该始终在最里层的嵌套元素上使用此注释,在那里使用才有效。如果要在特定的方法中取消显示某个警告,则应该注释该方法而不是注释它的类。
@SuppressWarnings注解表示抑制警告。
下面是一个使用@SuppressWarnings注解的例子:
@SuppressWarnings("unchecked")
public static void main(String[] args) {
List list = new ArrayList();
list.add("abc");
}
5、自定义注解:
使用@interface自定义注解时,自动继承了java.lang.annotation.Annotation接口,由编译程序自动完成其他细节。在定义注解时,不能继承其他的注解或接口。
自定义最简单的注解:
public @interface MyAnnotation {
}
使用自定义注解:
public class AnnotationTest2 {
@MyAnnotation
public void execute(){
System.out.println("method");
}
}
5.1、添加变量:
public @interface MyAnnotation {
String value1();
}
使用自定义注解:
public class AnnotationTest2 {
@MyAnnotation(value1="abc")
public void execute(){
System.out.println("method");
}
}
当注解中使用的属性名为value时,对其赋值时可以不指定属性的名称而直接写上属性值接口;除了value意外的变量名都需要使用name=value的方式赋值。
5.2、添加默认值:
public @interface MyAnnotation {
String value1() default "abc";
}
5.3、多变量使用枚举:
public @interface MyAnnotation {
String value1() default "abc";
MyEnum value2() default MyEnum.Sunny;
}
enum MyEnum{
Sunny,Rainy
}
使用自定义注解:
public class AnnotationTest2 {
@MyAnnotation(value1="a", value2=MyEnum.Sunny)
public void execute(){
System.out.println("method");
}
}
5.4、数组变量:
public @interface MyAnnotation {
String[] value1() default "abc";
}
使用自定义注解:
public class AnnotationTest2 {
@MyAnnotation(value1={"a","b"})
public void execute(){
System.out.println("method");
}
}
6、设置注解的作用范围:
@Documented
@Retention(value=RUNTIME)
@Target(value=ANNOTATION_TYPE)
public @interface Retention
指示注释类型的注释要保留多久。如果注释类型声明中不存在 Retention 注释,则保留策略默认为 RetentionPolicy.CLASS。
只有元注释类型直接用于注释时,Target 元注释才有效。如果元注释类型用作另一种注释类型的成员,则无效。
public enum RetentionPolicy
extends Enum<RetentionPolicy>
注释保留策略。此枚举类型的常量描述保留注释的不同策略。它们与 Retention 元注释类型一起使用,以指定保留多长的注释。
CLASS
编译器将把注释记录在类文件中,但在运行时 VM 不需要保留注释。
RUNTIME
编译器将把注释记录在类文件中,在运行时 VM 将保留注释,因此可以反射性地读取。
SOURCE
编译器要丢弃的注释。
@Retention注解可以在定义注解时为编译程序提供注解的保留策略。
属于CLASS保留策略的注解有@SuppressWarnings,该注解信息不会存储于.class文件。
6.1、在自定义注解中的使用例子:
@Retention(RetentionPolicy.CLASS)
public @interface MyAnnotation {
String[] value1() default "abc";
}
7、使用反射读取RUNTIME保留策略的Annotation信息的例子:
java.lang.reflect
接口 AnnotatedElement
所有已知实现类:
AccessibleObject, Class, Constructor, Field, Method, Package
表示目前正在此 VM 中运行的程序的一个已注释元素。该接口允许反射性地读取注释。由此接口中的方法返回的所有注释都是不可变并且可序列化的。调用者可以修改已赋值数组枚举成员的访问器返回的数组;这不会对其他调用者返回的数组产生任何影响。
如果此接口中的方法返回的注释(直接或间接地)包含一个已赋值的 Class 成员,该成员引用了一个在此 VM 中不可访问的类,则试图通过在返回的注释上调用相关的类返回的方法来读取该类,将导致一个 TypeNotPresentException。
isAnnotationPresent
boolean isAnnotationPresent(Class<? extends Annotation> annotationClass)
如果指定类型的注释存在于此元素上,则返回 true,否则返回 false。此方法主要是为了便于访问标记注释而设计的。
参数:
annotationClass - 对应于注释类型的 Class 对象
返回:
如果指定注释类型的注释存在于此对象上,则返回 true,否则返回 false
抛出:
NullPointerException - 如果给定的注释类为 null
从以下版本开始:
1.5
getAnnotation
<T extends Annotation> T getAnnotation(Class<T> annotationClass)
如果存在该元素的指定类型的注释,则返回这些注释,否则返回 null。
参数:
annotationClass - 对应于注释类型的 Class 对象
返回:
如果该元素的指定注释类型的注释存在于此对象上,则返回这些注释,否则返回 null
抛出:
NullPointerException - 如果给定的注释类为 null
从以下版本开始:
1.5
getAnnotations
Annotation[] getAnnotations()
返回此元素上存在的所有注释。(如果此元素没有注释,则返回长度为零的数组。)该方法的调用者可以随意修改返回的数组;这不会对其他调用者返回的数组产生任何影响。
返回:
此元素上存在的所有注释
从以下版本开始:
1.5
getDeclaredAnnotations
Annotation[] getDeclaredAnnotations()
返回直接存在于此元素上的所有注释。与此接口中的其他方法不同,该方法将忽略继承的注释。(如果没有注释直接存在于此元素上,则返回长度为零的一个数组。)该方法的调用者可以随意修改返回的数组;这不会对其他调用者返回的数组产生任何影响。
返回:
直接存在于此元素上的所有注释
从以下版本开始:
1.5
下面是使用反射读取RUNTIME保留策略的Annotation信息的例子:
自定义注解:
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
String[] value1() default "abc";
}
使用自定义注解:
public class AnnotationTest2 {
@MyAnnotation(value1={"a","b"})
@Deprecated
public void execute(){
System.out.println("method");
}
}
读取注解中的信息:
public static void main(String[] args) throws SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException {
AnnotationTest2 annotationTest2 = new AnnotationTest2();
//获取AnnotationTest2的Class实例
Class<AnnotationTest2> c = AnnotationTest2.class;
//获取需要处理的方法Method实例
Method method = c.getMethod("execute", new Class[]{});
//判断该方法是否包含MyAnnotation注解
if(method.isAnnotationPresent(MyAnnotation.class)){
//获取该方法的MyAnnotation注解实例
MyAnnotation myAnnotation = method.getAnnotation(MyAnnotation.class);
//执行该方法
method.invoke(annotationTest2, new Object[]{});
//获取myAnnotation
String[] value1 = myAnnotation.value1();
System.out.println(value1[0]);
}
//获取方法上的所有注解
Annotation[] annotations = method.getAnnotations();
for(Annotation annotation : annotations){
System.out.println(annotation);
}
}
8、限定注解的使用:
限定注解使用@Target。
@Documented
@Retention(value=RUNTIME)
@Target(value=ANNOTATION_TYPE)
public @interface Target
指示注释类型所适用的程序元素的种类。如果注释类型声明中不存在 Target 元注释,则声明的类型可以用在任一程序元素上。如果存在这样的元注释,则编译器强制实施指定的使用限制。 例如,此元注释指示该声明类型是其自身,即元注释类型。它只能用在注释类型声明上:
@Target(ElementType.ANNOTATION_TYPE)
public @interface MetaAnnotationType {
...
}
此元注释指示该声明类型只可作为复杂注释类型声明中的成员类型使用。它不能直接用于注释:
@Target({})
public @interface MemberType {
...
}
这是一个编译时错误,它表明一个 ElementType 常量在 Target 注释中出现了不只一次。例如,以下元注释是非法的:
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.FIELD})
public @interface Bogus {
...
}
public enum ElementType
extends Enum<ElementType>
程序元素类型。此枚举类型的常量提供了 Java 程序中声明的元素的简单分类。
这些常量与 Target 元注释类型一起使用,以指定在什么情况下使用注释类型是合法的。
ANNOTATION_TYPE
注释类型声明
CONSTRUCTOR
构造方法声明
FIELD
字段声明(包括枚举常量)
LOCAL_VARIABLE
局部变量声明
METHOD
方法声明
PACKAGE
包声明
PARAMETER
参数声明
TYPE
类、接口(包括注释类型)或枚举声明
注解的使用限定的例子:
@Target(ElementType.METHOD)
public @interface MyAnnotation {
String[] value1() default "abc";
}
9、在帮助文档中加入注解:
要想在制作JavaDoc文件的同时将注解信息加入到API文件中,可以使用java.lang.annotation.Documented。
在自定义注解中声明构建注解文档:
@Documented
public @interface MyAnnotation {
String[] value1() default "abc";
}
使用自定义注解:
public class AnnotationTest2 {
@MyAnnotation(value1={"a","b"})
public void execute(){
System.out.println("method");
}
}
10、在注解中使用继承:
默认情况下注解并不会被继承到子类中,可以在自定义注解时加上java.lang.annotation.Inherited注解声明使用继承。
@Documented
@Retention(value=RUNTIME)
@Target(value=ANNOTATION_TYPE)
public @interface Inherited
指示注释类型被自动继承。如果在注释类型声明中存在 Inherited 元注释,并且用户在某一类声明中查询该注释类型,同时该类声明中没有此类型的注释,则将在该类的超类中自动查询该注释类型。此过程会重复进行,直到找到此类型的注释或到达了该类层次结构的顶层 (Object) 为止。如果没有超类具有该类型的注释,则查询将指示当前类没有这样的注释。
注意,如果使用注释类型注释类以外的任何事物,此元注释类型都是无效的。还要注意,此元注释仅促成从超类继承注释;对已实现接口的注释无效。
除了文章中有特别说明,均为IT宅原创文章,转载请以链接形式注明出处。
本文链接:http://www.itzhai.com/java-based-notebook-annotation-annotation-introduction-and-use-custom-annotations.html
发表评论
-
toString
2013-09-28 11:00 876implements java.lang.Cloneabl ... -
匿名内部类 是否可以继承其它类,是否可以实现接口
2013-06-25 11:20 1492Inner Class(内部类)定义在类中的类。 Nested ... -
JAVA中的接口和抽象类(转)
2013-06-25 11:16 839在面向对象的概念中,我们知道所有的对象都是通过类来描绘的,但是 ... -
【解惑】领略Java内部类的“内部”
2013-06-25 10:57 842标签:Java 职场 休闲 内 ... -
Java内部类的使用小结
2013-06-25 10:51 974标签:Java 内部类 休闲 职场 内部类是指在一个外部类的内 ... -
java内部类的作用分析
2013-06-25 10:16 936提起Java内部类(Inner Class)可能很多人不太熟悉 ... -
java中Class.forName的作用
2013-06-20 11:36 1076http://www.cnblogs.com/pyrmkj/a ... -
编写你自己的单点登录(SSO)服务
2013-06-18 16:15 985http://blog.csdn.net/javachanne ... -
Windows和Linux环境下Memcached安装与配置
2013-06-08 14:32 950来源http://www.cnblogs.com/xd502d ... -
windows下安装memcached
2013-06-08 11:52 912来源http://kevin-gzhz.iteye.c ... -
分布式缓存系统Memcached学习心得(转)
2013-06-08 10:40 903来源http://www.blogjava.net/sword ... -
Java中的值传递和引用传递
2013-05-24 17:04 885来源http://www.cnblogs.com/clara/ ... -
java中的值传递和引用传递
2013-05-24 16:51 848来源http://www.blogjava.net/jiafa ... -
【状态保持】会话状态Session解析以及原理分析
2013-05-21 17:16 996来源http://www.cnblogs.com/wl ... -
log4j 详解
2013-05-21 16:16 885http://www.blogjava.net/hwpok/a ... -
静态导入Static import
2013-05-21 11:55 938http://www.cnblogs.com/mengdd/a ... -
Java 可变参数
2013-05-21 11:49 839http://www.cnblogs.com/whgw/arc ... -
java枚举类型
2013-05-21 11:45 927http://www.cnblogs.com/Fskjb/ar ... -
Struts2数据传输的背后机制:ValueStack(值栈)(转载)
2013-05-17 14:40 1091http://www.blogjava.net/freeman ... -
详细介绍Java垃圾回收机制
2013-05-17 11:16 967来源http://www.cnblogs.com/laoyan ...
相关推荐
java 自定义注解验证 可自己添加所需要的注解,本案例中只写了三个自定义注解类 本案例只花了半天时间,如有不好之处请多提提意见。谢谢!
包括Java自定义注解以及包括自定义注解的应用实例。以及注解相关知识的注解
自定义注解实现由类自定生成数据库中的表,适合各种类型的数据库,本案例主要实现的时sql server和oracle
java自定义注解实践,介绍详细!值得参考
简单demo,导入即可运行。
3、对spring aop认识模糊的,不清楚如何实现Java 自定义注解的 4、想看spring aop 注解实现记录系统日志并入库等 二、能学到什么 1、收获可用源码 2、能够清楚的知道如何用spring aop实现自定义注解以及注解的逻辑...
自定义注解和通过反射获取注解
这个一个自定义注解实现给注解传递伪动态参数的小案例,可以在此自定义注解的基础上来记录接口的调用记录。
Java基础复习笔记12Java自定义注解Annotation的使用
通过一个超市的自动售卖机的例子,详细说明了java的自定义注解的使用。
java自定义 注解 annotation、标签库tag、监听listener、junit简单测试代码
主要介绍了java 自定义注解的实例详解的相关资料,需要的朋友可以参考下
内容:拦截器的使用很简单,定义一个自己的拦截器,向配置中添加一下就可以使用。为了方便,之后又引入了注解。本文就将用简洁的代码构建一个springboot的拦截器。...oNoNeedToken.java 自定义注解
Java自定义注解程序Demo
真实案例!java自定义注解实战
# 自定义注解的规则: - 1.定义注解 - 2.定义注解的切面 - 3.使用注解
java 元注解+拦截器实现自定义注解 @CmwAutoWired:自定义依赖注入 注意:注入的接口和实现类需要在同一包名下,注解的是类则无限制 @FieldAnnotation:自定义属性注解 @MethodAnnotation:自定义方法注解 @...
excel导入动态校验,自定义注解动态校验
自定义注解实现拦截sql,并在sql中增加相应的条件 。 对应博客: https://blog.csdn.net/qq_37716298/article/details/120659139