Springboot注解类⾥⾯public@interfacexxx什么意思@interface 不是interface,是注解类 定义注解
是jdk1.5之后加⼊的,java没有给它新的关键字,所以就⽤@interface 这么个东西表⽰了
这个注解类,就是定义⼀个可⽤的注解,包括这个注解⽤于什么地⽅,是类,还是⽅法,还是property,还是⽅法⼊参等等
@Inherited //这个Annotation 可以被继承
@Documented //这个Annotation可以被写⼊javadoc
@Retention(RetentionPolicy.RUNTIME)
注解@Retention可以⽤来修饰注解,是注解的注解,称为元注解。
public enum RetentionPolicy {
SOURCE, // 编译器处理完Annotation后不存储在class中
CLASS, // 编译器把Annotation存储在class中,这是默认值
RUNTIME // 编译器把Annotation存储在class中,可以由虚拟机读取,反射需要
}
@Target:注解的作⽤⽬标
@Target(ElementType.TYPE) //接⼝、类、枚举、注解
@Target(ElementType.FIELD) //字段、枚举的常量
@Target(ElementType.METHOD) //⽅法
@Target(ElementType.PARAMETER) //⽅法参数
@Target(ElementType.CONSTRUCTOR) //构造函数
@Target(ElementType.LOCAL_VARIABLE)//局部变量
@Target(ElementType.ANNOTATION_TYPE)//注解
@Target(ElementType.PACKAGE) ///包
ElementType源码:
public enum ElementType {
TYPE, // 指定适⽤点为 class, interface, enum
FIELD, // 指定适⽤点为 field
METHOD, // 指定适⽤点为 method
PARAMETER, // 指定适⽤点为 method 的 parameter
CONSTRUCTOR, // 指定适⽤点为 constructor
LOCAL_VARIABLE, // 指定使⽤点为 局部变量
ANNOTATION_TYPE, //指定适⽤点为 annotation 类型
PACKAGE // 指定适⽤点为 package
}
Annotation的⼀般形式是 :
public @interface MyAnnotation {
String value() default "hahaha";
}
其实等同于
public class MyAnnotation extends java.lang.annotation.Annotation{
private String value = "hahaha";
public void setValue(String value){
this.value = value;
}
public String getValue(){
return value;
}
}
@MyAnnotation(value="hello") //对应Bean的set⽅法
Method method = Method("doSomthing", null); //取得被注释的⽅法,AnnotationTest.class为该⽅法所在的类
MyRetention mr = Annotation(MyRetention.class); //取得注释对象
String value = mr.value(); //取得value的值,对应Bean的get⽅法.
java.lang.annotation.Retention告诉编译器如何对待 Annotation,使⽤Retention时,需要提供java.lang.annotation.RetentionPolicy 的 枚举值.
package com.self;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface MyTarget
{ }
定义个⼀注解@MyTarget,⽤RetentionPolicy.RUNTIME修饰;parameter是什么意思啊
package com.self;
import flect.Method;
public class MyTargetTest
{
@MyTarget
public void doSomething()
{
System.out.println("hello world");
}
public static void main(String[] args) throws Exception
{
Method method = Method("doSomething",null);
if(method.isAnnotationPresent(MyTarget.class))//如果doSomething⽅法上存在注解@MyTarget,则为true
{
System.out.Annotation(MyTarget.class));
}
}
}
上⾯程序打印:@com.self.MyTarget(),如果RetentionPolicy值不为RUNTIME,则不打印。
@Retention(RetentionPolicy.SOURCE )
public @interface Override
@Retention(RetentionPolicy.SOURCE )
public @interface SuppressWarnings
@Retention(RetentionPolicy.RUNTIME )
public @interface Deprecated
由上可以看出,只有注解@Deprecated在运⾏时可以被JVM读取到
注解中可以定义属性,看例⼦:
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation
{
String hello() default "gege";
String hello() default "gege";
String world();
int[] array() default { 2, 4, 5, 6 };
EnumTest.TrafficLamp lamp() ;
TestAnnotation lannotation() default @TestAnnotation(value = "ddd");
Class style() default String.class;
}
上⾯程序中,定义⼀个注解@MyAnnotation,定义了6个属性,他们的名字为:
hello,world,array,lamp,lannotation,style.
属性hello类型为String,默认值为gege
属性world类型为String,没有默认值
属性array类型为数组,默认值为2,4,5,6
属性lamp类型为⼀个枚举,没有默认值
属性lannotation类型为注解,默认值为@TestAnnotation,注解⾥的属性是注解
属性style类型为Class,默认值为String类型的Class类型
看下⾯例⼦:定义了⼀个MyTest类,⽤注解@MyAnnotation修饰,注解@MyAnnotation定义的属性都赋了值
@MyAnnotation(hello = "beijing", world="shanghai",array={},lamp=TrafficLamp.RED,style=int.class)
public class MyTest
{
@MyAnnotation(lannotation=@TestAnnotation(value="baby"), world = "shanghai",array={1,2,3},lamp=TrafficLamp.YELLOW) @Deprecated
@SuppressWarnings("")
public void output()
{
System.out.println("output something!");
}
}
接着通过反射读取注解的信息:
public class MyReflection
{
public static void main(String[] args) throws Exception
{
MyTest myTest = new MyTest();
Class<MyTest> c = MyTest.class;
Method method = c.getMethod("output", new Class[] {});
//如果MyTest类名上有注解@MyAnnotation修饰,则为true
if(MyTest.class.isAnnotationPresent(MyAnnotation.class))
{
System.out.println("have annotation");
}
if (method.isAnnotationPresent(MyAnnotation.class))
{
method.invoke(myTest, null); //调⽤output⽅法
//获取⽅法上注解@MyAnnotation的信息
MyAnnotation myAnnotation = Annotation(MyAnnotation.class);
String hello = myAnnotation.hello();
String world = myAnnotation.world();
System.out.println(hello + ", " + world);//打印属性hello和world的值
System.out.println(myAnnotation.array().length);//打印属性array数组的长度
System.out.println(myAnnotation.lannotation().value()); //打印属性lannotation的值
System.out.println(myAnnotation.style());
}
//得到output⽅法上的所有注解,当然是被RetentionPolicy.RUNTIME修饰的
Annotation[] annotations = Annotations();
for (Annotation annotation : annotations)
{
System.out.println(annotation.annotationType().getName());
}
}
}
上⾯程序打印:
have annotation
output something!
gege, shanghai
3
3
baby
class java.lang.String
com.heima.annotation.MyAnnotation
java.lang.Deprecated
如果注解中有⼀个属性名字叫value,则在应⽤时可以省略属性名字不写。
可见,@Retention(RetentionPolicy.RUNTIME )注解中,RetentionPolicy.RUNTIME是注解属性值,属性名字是value,属性的返回类型是RetentionPolicy,如下:
public @interface MyTarget
{
String value();
}
可以这样⽤:
@MyTarget("aaa")
public void doSomething()
{
System.out.println("hello world");
}
注解@Target也是⽤来修饰注解的元注解,它有⼀个属性ElementType也是枚举类型,
值为:ANNOTATION_TYPE CONSTRUCTOR FIELD LOCAL_VARIABLE METHOD PACKAGE PARAMETER TYPE 如@Target(ElementType.METHOD) 修饰的注解表⽰该注解只能⽤来修饰在⽅法上。
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyTarget
{
String value() default "hahaha";
}
如把@MyTarget修饰在类上,则程序报错,如:
@MyTarget
public class MyTargetTest
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论