java注解
注解的定义和使用
1 2 3 4
| public @interface MyTest { String[] value(); int id(); }
|
和接口一样的定义,但前面多了一个@
使用方法
1 2 3
| @MyTest public class MyClass { }
|
元注解
字面意思,即最基本的注解。它可以用在其它注解上。
元注解有5种
@Retention 保留期
作用: 其作用是告诉编译器和JVM被注解的注解的存活期
取值 |
存活期 |
RetentionPolicy.SOURCE |
只在源码阶段,编译时丢弃 |
RetentionPolicy.CLASS |
编译时保留,但不加载入JVM |
RetentionPolicy.RUNTIME |
编译时保留,加载入JVM,可以获取 |
@Documented 文档
作用: 它的作用是能够将注解中的元素包含到 Javadoc 中去
@Target 限定注解对象
作用: 限定注解的对象
取值 |
对象 |
ElementType.ANNOTATION_TYPE |
可以给一个注解进行注解 |
ElementType.CONSTRUCTOR |
可以给构造方法进行注解 |
ElementType.FIELD |
可以给属性进行注解 |
ElementType.LOCAL_VARIABLE |
可以给局部变量进行注解 |
ElementType.METHOD |
可以给方法进行注解 |
ElementType.PACKAGE |
可以给一个包进行注解 |
ElementType.PARAMETER |
可以给一个方法内的参数进行注解 |
ElementType.TYPE |
可以给一个类型进行注解,比如类、接口、枚举 |
@Inherited 使注解可以随类继承
作用: 使注解可以随类继承
1 2 3 4 5 6 7 8 9 10 11 12
| import java.lang.annotation.Inherited;
@Inherited public @interface MyAnnotation { }
@MyAnnotation class test { }
class test2 extends test { }
|
上例中,test2
类也有和test
类一样的MyAnnotation
注解
@Repeatable 重复使用
作用: 对同一类多次打一个注解
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| import java.lang.annotation.Inherited; import java.lang.annotation.Repeatable;
public @interface MyAnnotation { role[] value(); }
@Inherited @Repeatable(MyAnnotation.class) @interface role { String value(); }
@role("富豪") class father { }
@role("画家") @role("富二代") class son extends father { }
|
java内置注解
@Deprecated 已抛弃
标记过时的类、属性、方法等
在ide里面,会有删除线表示过时方法
@Override 重写
不多说了
@SuppressWarnings 阻止警告
@SafeVarargs
如果你认为你的方法或者构造方法是类型安全的,那么你也就可以使用@SafeVarargs 来跳过@SuppressWarnings(“unchecked”)检查。
注解的提取
注解通过反射提取
1 2 3
| boolean isAnnotationPresent(Class) <A extends Annotation> A getAnnotation(Class) Annotation[] getAnnotations()
|
自己实现的注解默认不被编译器解析,请加上@Retention(RetentionPolicy.RUNTIME)
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 36 37 38 39 40 41 42 43 44 45
| import java.lang.annotation.*; import java.util.Arrays;
@Inherited @Retention(RetentionPolicy.RUNTIME) public @interface MyAnnotation { role[] value(); }
@Inherited @Repeatable(MyAnnotation.class) @Retention(RetentionPolicy.RUNTIME) @interface role { String value(); }
@role("富豪") class father { }
@role("画家") @role("富二代") class son extends father { }
class test { public static void main(String[] args) { Annotation[] role = son.class.getAnnotations(); System.out.println(Arrays.toString(role)); } }
|
作用
给编译器或者APT用,或者说,取决于自己的想法
- 将需要检查的方法打上
@check
,来进行检查
- 利用注解做路由
- 异步代码标记
实战
下面是一个简单的url路由解析器和定义,文件不多,就5个。带师傅们当个乐就好,主要是去理解其中的含义
RequestMethud.java
1 2 3 4 5 6
| package RouteTest.RouteRequest;
public enum RequestMethod { GET, POST }
|
Request.java
1 2 3 4 5 6 7 8 9 10 11 12 13
| package RouteTest.RouteRequest;
import java.lang.annotation.Repeatable; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy;
@Repeatable(Requests.class) @Retention(RetentionPolicy.RUNTIME) public @interface Request { String path(); RequestMethod[] method(); }
|
Requests.java
1 2 3 4 5 6 7 8 9
| package RouteTest.RouteRequest;
import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME) public @interface Requests { Request[] value(); }
|
Route.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| package RouteTest.Route;
import RouteTest.RouteRequest.Request; import static RouteTest.RouteRequest.RequestMethod.*;
public class Route {
@Request(path="/", method = GET) @Request(path = "/index", method = {GET, POST}) public Object index() { return "index"; }
@Request(path="/test", method = POST) public Object test() { return "test"; } }
|
Analysis.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 36 37 38 39 40 41 42 43 44 45 46 47 48 49
| package RouteTest.RouteAnalysis;
import RouteTest.Route.Route; import RouteTest.RouteRequest.Request; import RouteTest.RouteRequest.Requests;
import java.lang.reflect.Method; import java.util.HashMap;
public class Analysis { public HashMap<String, Method> RouteAnalysis() { HashMap<String, Method> urlMap = new HashMap<>();
Route router = new Route(); Method[] r = router.getClass().getDeclaredMethods();
for (Method m : r) { Request req = getRequest(m); if (req != null) { urlMap.put(req.path(), m); }
Requests reqs = getRequests(m); if (reqs != null) { for (Request reqFromReqs : reqs.value()) { urlMap.put(reqFromReqs.path(), m); } } }
return urlMap; }
private Request getRequest(Method m) { return m.getAnnotation(Request.class); }
private Requests getRequests(Method m) { return m.getAnnotation(Requests.class); } }
class test { public static void main(String[] args) { Analysis test = new Analysis(); System.out.println(test.RouteAnalysis().get("/index")); } }
|