注解
在写spring项目的时候,经常会用到各种各样的注解,但是平时只是使用,并没有理解注解是怎么起作用的。今天写了一篇Demo,尝试使用一下注解。
注解和注释完全不同:
- 注释是给开发人员看的,用来对程序代码进行解释,方便阅读代码。
- 注解是给程序看的,会影响程序的编译和运行。
JDK中的注解
@Override: 用来检测被注解的方法是否继承自父类或接口。
@FunctionalInterface:用于声明一个接口是函数式接口。函数式接口只能有一个抽象方法,但可以有多个默认方法或静态方法。
@Deprecated:用于标记已过时的类、方法或字段。编译器会在使用被标记的内容时发出警告,提醒开发者尽量避免使用它们。
@Target注解决定了你可以在代码中的哪些位置使用特定的注解
它接受一个 ElementType 类型的参数,表示注解可以应用的目标类型。
`ElementType.TYPE`:可以应用在类、接口、枚举类型上。
`ElementType.FIELD`:可以应用在字段上。
`ElementType.METHOD`:可以应用在方法上。
`ElementType.PARAMETER`:可以应用在方法参数上。
`ElementType.CONSTRUCTOR`:可以应用在构造函数上。
`ElementType.LOCAL_VARIABLE`:可以应用在局部变量上。
`ElementType.ANNOTATION_TYPE`:可以应用在注解上。
`ElementType.PACKAGE`:可以应用在包上。
@Retention指定注解的保留域
具有三个参数
`RetentionPolicy.SOURCE`:表示注解仅存在于源代码中,在编译时会被丢弃。这意味着在编译后的字节码中不会包含这些注解信息,也不会被反射等操作获取到。
`RetentionPolicy.CLASS`:表示注解会存在于编译后的字节码中,但在运行时会被丢弃。这意味着在运行时无法通过反射获取到这些注解信息。
`RetentionPolicy.RUNTIME`:表示注解会一直存在于运行时环境中,可以通过反射等机制获取到。这种保留策略允许在运行时使用反射机制来读取和处理注解信息。
小Demo
首先创建一个注解
package myAnnotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(value = ElementType.METHOD)
@Retention(value = RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
}
在一个方法上使用这个注解
package myAnnotation;
public class AnnotationDemo {
@MyAnnotation
public void init(){
System.out.println("init...");
}
}
利用反射发现注解,并执行对应的方法
package myAnnotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class Test {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
Class clazz = Class.forName("myAnnotation.AnnotationDemo");
Method[] methods = clazz.getMethods();
for (Method method : methods) {
boolean annotationPresent = method.isAnnotationPresent(MyAnnotation.class);
if (annotationPresent) {
System.out.println(method.getName());
method.invoke(clazz.getConstructor(null).newInstance(null), null);
}
}
}
}