注解类
package com.ww.common.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @Auther: Ace Lee
* @Date: 2019/3/16 17:14
*/
@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
String color() default "blue";
String value();
}
测试类
package com.ww.common.annotation;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.function.Predicate;
/**
* @Auther: Ace Lee
* @Date: 2019/3/16 17:17
*/
@MyAnnotation("我是value的值")
public class MyAnnotationTest {
public static void main(String[] args) {
MyAnnotation myAnnotation = MyAnnotationTest.class.getAnnotation(MyAnnotation.class);
if (null==myAnnotation){
System.out.println("yes");
}else {
System.out.println(myAnnotation.color());
System.out.println(myAnnotation.value());
}
Method[] methods = MyAnnotationTest.class.getMethods();
if (methods.length>0){
Predicate<Method> name=(method -> method.getName().equals("sayHello"));
Arrays.stream(methods).filter(name).forEach(
method -> System.out.println(
"name="+method.getName()+", annotation="+method.getAnnotation(MyAnnotation.class).value()));
}
}
@MyAnnotation("我是方法的value值")
public void sayHello(){
System.err.println("Hello world!");
}
}
解释说明
@Target:用于描述注解的使用范围(即:被描述的注解可以用在什么地方)注解(annotation)可被用于 packages、types(类、接口、枚举、Annotation类型)、类型成员(方法、构造方法、成员变量、枚举值)、方法参数和本地变量(如循环变量、catch参数)。在注解类型的声明中使用了target可更加明晰其修饰的目标。取值(ElementType)有:
- ElementType.ANNOTATION_TYPE 可以应用于注释类型。
- ElementType.CONSTRUCTOR 可以应用于构造函数。
- ElementType.FIELD 可以应用于字段或属性。
- ElementType.LOCAL_VARIABLE 可以应用于局部变量。
- ElementType.METHOD 可以应用于方法级注释。
- ElementType.PACKAGE 可以应用于包声明。
- ElementType.PARAMETER 可以应用于方法的参数。
- ElementType.TYPE 可以应用于类的任何元素。
public enum ElementType {
/** Class, interface (including annotation type), or enum declaration */
TYPE,
/** Field declaration (includes enum constants) */
FIELD,
/** Method declaration */
METHOD,
/** Formal parameter declaration */
PARAMETER,
/** Constructor declaration */
CONSTRUCTOR,
/** Local variable declaration */
LOCAL_VARIABLE,
/** Annotation type declaration */
ANNOTATION_TYPE,
/** Package declaration */
PACKAGE,
/**
* Type parameter declaration
*
* @since 1.8
*/
TYPE_PARAMETER,
/**
* Use of a type
*
* @since 1.8
*/
TYPE_USE
}
@Retention:@Retention定义了该注解被保留的时间长短:某些注解仅出现在源代码中,而被编译器丢弃;而另一些却被编译在class文件中;编译在class文件中的注解可能会被虚拟机忽略,而另一些在class被装载时将被读取(请注意并不影响class的执行,因为注解与class在使用上是被分离的)。使用这个meta-Annotation可以对注解的“生命周期”限制。作用:表示需要在什么级别保存该注释信息,用于描述注解的生命周期(即:被描述的注解在什么范围内有效) 取值(RetentionPoicy)有:
- SOURCE:在源文件中有效(即源文件保留)
- CLASS:在class文件中有效(即class保留)
- RUNTIME:在运行时有效(即运行时保留)
public enum RetentionPolicy {
/**
* Annotations are to be discarded by the compiler.
*/
SOURCE,
/**
* Annotations are to be recorded in the class file by the compiler
* but need not be retained by the VM at run time. This is the default
* behavior.
*/
CLASS,
/**
* Annotations are to be recorded in the class file by the compiler and
* retained by the VM at run time, so they may be read reflectively.
*
* @see java.lang.reflect.AnnotatedElement
*/
RUNTIME
}
PS:注解只有一个成员时,按规范写成value(),当然不这么写不会报错。如果不设置默认值,那么使用注解时必须要传值。只有类可以被注解,因为接口或者抽象类并不能被注解。