Java 自定义注解
JDK 内置注解
-
@Override, 重载
-
@SuppressWarnings, 抑制警告信息
-
@Deprecated, 标注方法已过时,那么在编译的时候,编译器会发出相关警告
-
@SafeVarargs
-
@FunctionInterface
@Retention 策略设置为:
- SOURCE,那么在 javac 阶段注解会有效,编译之后注解将会被抛弃
- CLASS,那么注解将会被编译到 class 文件中,但它不能在运行时通过反射获取
- RUNTIME,那么注解将会被编译到 class 文件中,并能在运行时通过反射获取
@Documented
表示是否允许 javadoc 或相关工具为这个注解生成文档
@Inherited
表示注解是否可以被子类继承。
@Target
目标。
表示这个注解可以放到哪些元素上面。如果不设定,那么注解可以放置到任何元素上。
可以有很多选项,比如:
- ElementType.TYPE,可以放到类、接口、枚举类上面
- ElementType.METHOD,可以放到方法上面
- ElementType.PARAMETER,可以放到参数上面
在这里我以 maven项目 演示
配置pom.xml文件
完整的pom.xml文件
1 <?xml version="1.0" encoding="UTF-8"?> 2 3 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 5 <modelVersion>4.0.0</modelVersion> 6 7 <groupId>com.oukele.annotationDemo</groupId> 8 <artifactId>AnnotationDemo</artifactId> 9 <version>1.0-SNAPSHOT</version> 10 11 <name>AnnotationDemo</name> 12 <!-- FIXME change it to the project's website --> 13 <url>http://www.example.com</url> 14 15 <properties> 16 <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> 17 <maven.compiler.source>1.7</maven.compiler.source> 18 <maven.compiler.target>1.7</maven.compiler.target> 19 </properties> 20 21 <!--依赖--> 22 <dependencies> 23 24 <!--单元测试--> 25 <dependency> 26 <groupId>junit</groupId> 27 <artifactId>junit</artifactId> 28 <version>4.11</version> 29 <scope>test</scope> 30 </dependency> 31 32 <!--reflections 依赖--> 33 <dependency> 34 <groupId>org.reflections</groupId> 35 <artifactId>reflections</artifactId> 36 <version>0.9.10</version> 37 </dependency> 38 39 </dependencies> 40 41 <build> 42 <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) --> 43 <plugins> 44 <plugin> 45 <artifactId>maven-clean-plugin</artifactId> 46 <version>3.0.0</version> 47 </plugin> 48 <!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging --> 49 <plugin> 50 <artifactId>maven-resources-plugin</artifactId> 51 <version>3.0.2</version> 52 </plugin> 53 <plugin> 54 <artifactId>maven-compiler-plugin</artifactId> 55 <version>3.7.0</version> 56 </plugin> 57 <plugin> 58 <artifactId>maven-surefire-plugin</artifactId> 59 <version>2.20.1</version> 60 </plugin> 61 <plugin> 62 <artifactId>maven-jar-plugin</artifactId> 63 <version>3.0.2</version> 64 </plugin> 65 <plugin> 66 <artifactId>maven-install-plugin</artifactId> 67 <version>2.5.2</version> 68 </plugin> 69 <plugin> 70 <artifactId>maven-deploy-plugin</artifactId> 71 <version>2.8.2</version> 72 </plugin> 73 </plugins> 74 </pluginManagement> 75 </build> 76 77 </project>
项目结构:
IAnimal为自定义的注解类
代码:
1 package com.oukele.annotationDemo.animal; 2 3 4 import java.lang.annotation.ElementType; 5 import java.lang.annotation.Retention; 6 import java.lang.annotation.RetentionPolicy; 7 import java.lang.annotation.Target; 8 9 @Target({ElementType.TYPE,ElementType.METHOD})// TYPE --> @IAnimal注解可以放在类上, METHOD --> @IAnimal注解也可以放在方法上 10 @Retention(RetentionPolicy.RUNTIME)//项目运行时 启用注解 11 public @interface IAnimal { 12 //vaule 默认为空 13 String value() default ""; 14 15 }
在animal包中 创建一个Cat类
在test文件夹中的AppTest测试类的代码
1 package com.oukele.annotationDemo; 2 3 4 import com.oukele.annotationDemo.animal.IAnimal; 5 import org.junit.Test; 6 import org.reflections.Reflections; 7 8 import java.lang.annotation.Annotation; 9 import java.lang.reflect.Method; 10 import java.util.Set; 11 12 13 public class AppTest { 14 15 @Test 16 public void Test1() { 17 18 //使用reflections 快速读取注解 19 //创建reflections对象 并 扫描 前缀为 com.oukele.annotationDemo的文件下所有类 20 Reflections reflections = new Reflections("com.oukele.annotationDemo"); 21 //读取 IAnimal 注解 22 Set<Class<?>> clazzs = reflections.getTypesAnnotatedWith(IAnimal.class); 23 24 //遍历所有使用 @IAnimal注解 的类 25 for (Class<?> aClass : clazzs) { 26 //获取当前使用注解的类 27 IAnimal annotation = aClass.getAnnotation(IAnimal.class); 28 System.out.println("类名:"+aClass.getSimpleName()+" 注解值: "+ annotation.value() ); 29 //遍历所有使用 @IAnimal注解 的方法 30 for (Method method : aClass.getMethods()) { 31 IAnimal annotation1 = method.getAnnotation(IAnimal.class); 32 //如果方法 没使用 注解 则跳过 33 if(annotation1 != null){ 34 System.out.println("方法名:"+method.getName()+" 注解值: "+annotation1.value()); 35 } 36 37 } 38 } 39 40 41 } 42 43 }
结果:
另一种实现方法:
1 package com.oukele.annotationDemo; 2 3 4 import com.oukele.annotationDemo.animal.Cat; 5 import com.oukele.annotationDemo.animal.IAnimal; 6 import org.junit.Test; 7 import org.reflections.Reflections; 8 9 import java.lang.reflect.Method; 10 import java.lang.reflect.Modifier; 11 import java.util.Set; 12 13 14 public class AppTest { 15 16 17 18 19 @Test 20 public void Test2(){ 21 getAnnotation(Cat.class); 22 23 } 24 25 public void getAnnotation(Class<?> clazz ){ 26 //获取一个类的注解 27 //加载类 28 // Class<?> clazz == Class<Cat> catClass = Cat.class; 29 //判断这个类是否有注解,有则返回true 30 if(clazz.isAnnotationPresent(IAnimal.class)){ 31 //获取注解 32 IAnimal annotation = clazz.getAnnotation(IAnimal.class); 33 System.out.println("类名:"+clazz.getSimpleName()+" 注解值: "+annotation.value() ); 34 35 for (Method method : clazz.getMethods()) { 36 //获取方法上的注解 37 IAnimal annotation1 = method.getAnnotation(IAnimal.class); 38 //判断这个方法是否有注解 如果此方法没有注解 那么它的annotation1值是null 39 if(annotation1 != null ){ 40 System.out.println( 41 "方法:"+ Modifier.toString(method.getModifiers())+" " 42 +method.getReturnType()+" "+method.getName()+"(){} 注解值: "+annotation1.value() 43 ); 44 } 45 } 46 } 47 } 48 49 }
结果: