Java注解Annotation与自定义注解详解
概述
Java注解是在Java5中加入的新特性,是代码中的特殊标记,用于给类、方法、变量等元素添加附加信息,这些信息在编译、运行时处理或者是在代码分析的时候会被读取。注解可以看作是一种高级的Java注释,它与代码有紧密的联系。
Java注解可以分为三类:
- 预定义注解:JDK提供的注解,例如
@Override
,@Deprecated
,@SuppressWarnings
。 - 元注解:用于自定义注解的注解,例如
@Retention
,@Target
,@Documented
。 - 自定义注解:用户自己定义的注解,可以用
@interface
关键字定义。
预定义注解
@Override
指明某一个方法覆盖了父类的方法,如果父类中没有该方法,使用该注解会导致编译错误。
@override
public void foo() {
// some code here
}
@Deprecated
标记一个方法或类已经弃用,不再推荐使用。
@Deprecated
public class OldClass {
// some code here
}
@SuppressWarnings
指定一种或多种不显示任何编译器警告,这样可以防止出现不必要的编译警告。
@SuppressWarnings("unchecked")
List<String> list = new ArrayList();
元注解
@Retention
指定注解运行时生命周期。取值为RetentionPolicy
中的枚举值,有三种可选:SOURCE
,CLASS
,RUNTIME
。
SOURCE
:只在源代码中存在,编译时就会被忽略。CLASS
:编译时被存储在class文件中,但是在运行时不会被JVM保留。RUNTIME
:运行时存在,可以通过反射获取注解信息。
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
// some code here
}
@Target
指定注解应用的目标类型,取值为ElementType
中的枚举值,可以单独使用也可以组合使用。
@Target(ElementType.TYPE)
public @interface MyAnnotation {
// some code here
}
@Documented
将注解包含在JavaDoc中。
@Documented
public @interface MyAnnotation {
// some code here
}
自定义注解
自定义注解是使用@interface
关键字定义的,它和定义Java类很像,可以定义元素,方法,抛出的异常等等。在使用自定义注解时,需要给注解元素设置值。下面给出一个简单的例子:
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
String value() default "";
int id();
String[] names();
}
该注解有三个元素:value
,id
,names
,对应不同的数据类型,其中value
和id
均为必填,value
默认值为""。下面给出一个使用该注解的例子:
@MyAnnotation(id=1, names={"abc", "def"})
public class Test {
@MyAnnotation(id=2)
public void foo() {
// some code here
}
}
示例说明
示例1:用自定义注解实现权限控制
定义一个注解@Permission
,用于标注有权限限制的方法。同时编写一个PermissionHandler
类,用于获取当前用户权限,并检查访问该方法所需的权限是否满足。
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Permission {
String[] value();
}
public class PermissionHandler {
public static boolean hasPermission(String[] permissions) {
// some code here
return true;
}
public static boolean checkPermission(Method method) {
boolean hasPermission = true;
if (method.isAnnotationPresent(Permission.class)) {
Permission permission = method.getAnnotation(Permission.class);
hasPermission = hasPermission(permission.value());
}
return hasPermission;
}
}
下面定义一个测试类,并在其中使用@Permission
注解:
public class Test {
@Permission({"read", "write"})
public void foo() {
System.out.println("do foo");
}
public void bar() {
System.out.println("do bar");
}
public static void main(String[] args) throws NoSuchMethodException {
Test test = new Test();
Method fooMethod = test.getClass().getMethod("foo");
if (PermissionHandler.checkPermission(fooMethod)) {
test.foo();
}
Method barMethod = test.getClass().getMethod("bar");
if (PermissionHandler.checkPermission(barMethod)) {
test.bar();
}
}
}
运行上述测试代码,当用户具备read
和write
权限时,执行foo
方法,否则不执行。
示例2:用注解生成文档
定义一个注解@Doc
,用于标注需要生成文档的类和方法,同时编写一个DocGenerator
类,用于生成文档。
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Doc {
String desc();
String author();
String date();
}
public class DocGenerator {
public static void generate(Class<?> clazz) {
if (clazz.isAnnotationPresent(Doc.class)) {
Doc classDoc = clazz.getAnnotation(Doc.class);
System.out.println("Class: " + clazz.getSimpleName() + ":\n " + classDoc.desc() +
" By " + classDoc.author() + " On " + classDoc.date());
}
Method[] methods = clazz.getMethods();
for (Method method : methods) {
if (method.isAnnotationPresent(Doc.class)) {
Doc methodDoc = method.getAnnotation(Doc.class);
System.out.println("Method: " + method.getName() + ":\n " + methodDoc.desc() +
" By " + methodDoc.author() + " On " + methodDoc.date());
}
}
}
}
下面定义一个测试类,并在其中使用@Doc
注解:
@Doc(desc="This is a test class", author="John", date="2021-08-01")
public class Test {
@Doc(desc="This is a test method", author="John", date="2021-08-02")
public void foo() {
System.out.println("do foo");
}
public static void main(String[] args) {
DocGenerator.generate(Test.class);
}
}
运行上述测试代码,将会生成如下的文档:
Class: Test:
This is a test class By John On 2021-08-01
Method: foo:
This is a test method By John On 2021-08-02
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java注解Annotation与自定义注解详解 - Python技术站