Java注解教程及自定义注解

创建Java自定义注解

创建自定义注解和创建一个接口相似,但是注解的interface关键字需要以@符号开头。我们可以为注解声明方法。我们先来看看注解的例子,然后我们将讨论他的一些特性。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package net.yangki.annotations;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Documented
@Target(ElementType.METHOD)
@Inherited
@Retention(RetentionPolicy.RUNTIME)
public @interface MethodInfo{
String author() default 'yangki';
String date();
int revision() default 1;
String comments();
}

  • 注解方法不能带有参数;
  • 注解方法返回值类型限定为:基本类型、StringEnumsAnnotation或者是这些类型的数组;
  • 注解方法可以有默认值;
  • 注解本身能够包含元注解,元注解被用来注解其它注解。

这里有四种类型的元注解:

  1. @Documented —— 指明拥有这个注解的元素可以被javadoc此类的工具文档化。这种类型应该用于注解那些影响客户使用带注释的元素声明的类型。如果一种声明使用Documented进行注解,这种类型的注解被作为被标注的程序成员的公共API。
  2. @Target——指明该类型的注解可以注解的程序元素的范围。该元注解的取值可以为TYPE,METHOD,CONSTRUCTOR,FIELD等。如果Target元注解没有出现,那么定义的注解可以应用于程序的任何元素。
  3. @Inherited——指明该注解类型被自动继承。如果用户在当前类中查询这个元注解类型并且当前类的声明中不包含这个元注解类型,那么也将自动查询当前类的父类是否存在Inherited元注解,这个动作将被重复执行知道这个标注类型被找到,或者是查询到顶层的父类。
  4. @Retention——指明了该Annotation被保留的时间长短。RetentionPolicy取值为SOURCE,CLASS,RUNTIME

Java内建注解

Java提供了三种内建注解。

  1. @Override——当我们想要复写父类中的方法时,我们需要使用该注解去告知编译器我们想要复写这个方法。这样一来当父类中的方法移除或者发生更改时编译器将提示错误信息。
  2. @Deprecated——当我们希望编译器知道某一方法不建议使用时,我们应该使用这个注解。Java在javadoc 中推荐使用该注解,我们应该提供为什么该方法不推荐使用以及替代的方法。
  3. @SuppressWarnings——这个仅仅是告诉编译器忽略特定的警告信息,例如在泛型中使用原生数据类型。它的保留策略是SOURCE(译者注:在源文件中有效)并且被编译器丢弃。

我们来看一个java内建注解的例子参照上边提到的自定义注解。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
package net.yangki.annotations;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.List;
public class AnnotationExample {
public static void main(String[] args) {
}
@Override
@MethodInfo(author = 'yangki', comments = 'Main method', date = 'Nov 17 2012', revision = 1)
public String toString() {
return 'Overriden toString method';
}
@Deprecated
@MethodInfo(comments = 'deprecated method', date = 'Nov 17 2015')
public static void oldMethod() {
System.out.println('old method, don't use it.');
}
@SuppressWarnings({ 'unchecked', 'deprecation' })
@MethodInfo(author = 'yangki', comments = 'Main method', date = 'Nov 17 2015', revision = 10)
public static void genericsTest() throws FileNotFoundException {
List l = new ArrayList();
l.add('abc');
oldMethod();
}
}

Java注解解析

我们将使用反射技术来解析java类的注解。那么注解的RetentionPolicy应该设置为RUNTIME否则java类的注解信息在执行过程中将不可用那么我们也不能从中得到任何和注解有关的数据。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
package net.yangki.annotations;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
public class AnnotationParsing {
public static void main(String[] args) {
try {
for (Method method : AnnotationParsing.class
.getClassLoader()
.loadClass(('net.yangki.annotations.AnnotationExample'))
.getMethods()) {
// checks if MethodInfo annotation is present for the method
if (method.isAnnotationPresent(com.journaldev.annotations.MethodInfo.class)) {
try {
// iterates all the annotations available in the method
for (Annotation anno : method.getDeclaredAnnotations()) {
System.out.println('Annotation in Method ''+ method + '' : ' + anno);
}
MethodInfo methodAnno = method.getAnnotation(MethodInfo.class);
if (methodAnno.revision() == 1) {
System.out.println('Method with revision no 1 = '+ method);
}
} catch (Throwable ex) {
ex.printStackTrace();
}
}
}
} catch (SecurityException | ClassNotFoundException e) {
e.printStackTrace();
}
}
}

运行上面程序将输出:

1
2
3
4
5
6
Annotation in Method 'public java.lang.String net.yangki.annotations.AnnotationExample.toString()' : @net.yangki.annotations.MethodInfo(author=yangki, revision=1, comments=Main method, date=Nov 17 2015)
Method with revision no 1 = public java.lang.String net.yangki.annotations.AnnotationExample.toString()
Annotation in Method 'public static void net.yangki.annotations.AnnotationExample.oldMethod()' : @java.lang.Deprecated()
Annotation in Method 'public static void net.yangki.annotations.AnnotationExample.oldMethod()' : @net.yangki.annotations.MethodInfo(author=yangki, revision=1, comments=deprecated method, date=Nov 17 2015)
Method with revision no 1 = public static void net.yangki.annotations.AnnotationExample.oldMethod()
Annotation in Method 'public static void net.yangki.annotations.AnnotationExample.genericsTest() throws java.io.FileNotFoundException' : @net.yangki.annotations.MethodInfo(author=yangki, revision=10, comments=Main method, date=Nov 17 2015)
如果你喜欢我的blog,请鼓励我一杯咖啡☕️
0%