注解-学习笔记

134 阅读2分钟

注解

在写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);  
            }  
        }  
    }  
}