java注解 源码_Java源码赏析(四)Java常见注解

元注解

@Target :标识注解的目标,默认为所有

ElementType.TYPE(用于类)

ElementType.FIELD(用于域,包括enum)

ElementType.METHOD(用于方法)

ElementType.PARAMETER(用于正式参数)

ElementType.CONSTRUCTOR(类型构造方法)

ElementType.LOCAL_VARIABLE(用于本地变量)

ElementType.ANNOTATION_TYPE(用于注解)

ElementType.PACKAGE(用于包)

ElementType.TYPE_PARAMETER(java8,用于输入参数)

ElementType.TYPE_USE (java8,用于类型)

@Retention:注解保留到哪

RetentionPolicy.SOURCE(只保留到源码,编译为.class文件时忽略)

RetentionPolicy.CLASS(只保留到.class文件,运行时忽略,default默认)

RetentionPolicy.RUNTIME(运行时保留,可以通过反射机制读取注解的信息。)

@Documented:将此注解保存在 Javadoc 中

@Inherited:允许子类继承父类的注解

@Repeatable:用于重复使用注解(Java8新增)

常用注解

一、@Override

常用于重写父类的方法,或实现接口的方法,若不满足则报错。

packagejava.lang;import java.lang.annotation.*;/*** 使用在方法上,只存在在源码上*/@Target(ElementType.METHOD)

@Retention(RetentionPolicy.SOURCE)public @interfaceOverride {

}

二、

e84d82d1f87752d38e1f933597406afb.png@Deprecated

常用于标注一个方法被弃用。

packagejava.lang;import java.lang.annotation.*;import static java.lang.annotation.ElementType.*;/*** 记录JavaDoc,保留至运行时,可使用在构造方法,属性(包括枚举),本地变量,方法,包,公共参数和类*/@Documented

@Retention(RetentionPolicy.RUNTIME)

@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE})public @interfaceDeprecated {

}

三、@SuppressWarnings

常用于忽略特定警告,@SuppressWarnings("unchecked", "deprecation")可以同时忽略多个警告。

packagejava.lang;import java.lang.annotation.*;import static java.lang.annotation.ElementType.*;/*** 在类型、域、方法、正是参数、构造方法、本地变量上使用,只存在于源码*/@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})

@Retention(RetentionPolicy.SOURCE)public @interfaceSuppressWarnings {/*** 一般取 unchecked/deprecation,表示忽略 unchecked/deprecation 警告信息*/String[] value();

}

四、@SafeVarargs (Java7)

常用于抑制varargs相关的未检查警告,一般只能用于static、final方法

packagejava.lang;import java.lang.annotation.*;/*** 能记录JavaDoc,保留至运行时,使用在构造方法和方法上*/@Documented

@Retention(RetentionPolicy.RUNTIME)

@Target({ElementType.CONSTRUCTOR, ElementType.METHOD})public @interface SafeVarargs {}

五、@FunctionalInterface (Java8)

编译器检测接口是否符合函数式接口定义

packagejava.lang;import java.lang.annotation.*;/*** 能记录JavaDoc,存在于运行时,只能使用在类上*/@Documented

@Retention(RetentionPolicy.RUNTIME)

@Target(ElementType.TYPE)public @interface FunctionalInterface {}

自定义注解

首先定义一个注解

packagecom.example.demo.util.annotation;import java.lang.annotation.*;

@Retention(RetentionPolicy.RUNTIME)

@Target(ElementType.FIELD)

@Documented

@Inheritedpublic @interfaceMyAnnotation {

String value()default "001";

}

可以看到,在Student的sNo属性上使用了该注解

packagecom.example.demo.util.annotation;importlombok.Data;importlombok.AllArgsConstructor;importlombok.NoArgsConstructor;@Data

@AllArgsConstructor

@NoArgsConstructorpublic classStudent {

@MyAnnotationprivateString sNo;privateString sName;

}

处理注解

packagecom.example.demo.util.annotation;importjava.lang.reflect.Field;importjava.lang.reflect.InvocationTargetException;importjava.lang.reflect.Method;importjava.util.Objects;public classAnnotationTest {public static voidmain(String[] args) {//创建一个学号为 002 的学生 kw

Student student = new Student("002", "kw");//获取学生对象对应的类

Class extends Student> clazz =student.getClass();//获取学生类的属性

Field[] declaredFields =clazz.getDeclaredFields();/**循环判断是否存在注解@MyAnnotation

* 若存在则获取该属性的set方法

* 并使用该方法将值改为@MyAnnotation的value值*/@MyAnnotation的valuefor(Field field: declaredFields) {if (field.isAnnotationPresent(MyAnnotation.class)) {

MyAnnotation annotation= field.getAnnotation(MyAnnotation.class);if(Objects.nonNull(annotation)) {

String name=field.getName();try{

Method setMethod=clazz.getDeclaredMethod("set" + name.substring(0, 1).toUpperCase() + name.substring(1), String.class);

String annotationValue=annotation.value();

setMethod.invoke(student, annotationValue);

}catch(NoSuchMethodException e) {

e.printStackTrace();

}catch(IllegalAccessException e) {

e.printStackTrace();

}catch(InvocationTargetException e) {

e.printStackTrace();

}

}

}

}//打印

System.out.println(student);

}

}/**输出

Student(sNo=001, sName=kw)*/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值