Java学习笔记@注解

笔者: unirithe

日期: 11/13/2021

注解概述

  • Java 注解 (Annotation) 又称 Java标注,是JDK5.0 引入的一种注释机制
  • Java 语言中的类、构造器、方法、成员变量、参数等都可以被注解进行标注

注解的作用:对Java中类、方法、成员变量做标记,然后进行特殊处理

自定义注解

代码格式

public @interface 注解名称{
    public 属性名称 属性名() default 默认值;
}

范例:自定义注解的使用,可标记各种对象包括类、构造器方法、成员变量

@interface UserInfo{
    String id();
    String [] hobby() default {"无"};
    int age() default 3;
}

@UserInfo(id="123", hobby={"吃饭", "睡觉"}, age = 21)
public class Demo{

    @UserInfo(id="456")
    public Demo(){}
    @UserInfo(id="abc")
    public static void main(String[] args) {
        
        @UserInfo(id="123")
        int a = 0;
    }
}

value特殊属性

  • value属性,如果只有一个value属性的情况下,则可忽略value字符串,多个没默认值的属性除外
@interface UserInfo{
    String id() default "uni";
    String value();
}
@UserInfo("test")
public class Demo{public static void main(String[] args) {}}

元注解

指规范注解的注解

常见元注解:

  • @Target : 规定自定义注解适用范围
  • @Retention:规定注解的生命周期

范例:规定注解只能针对方法

@Target({ElementType.METHOD})
@interface MyTest{
    String value();
}

@Target

该注解可使用的值都在import java.lang.annotation.ElementType 枚举类中

变量 描述
TYPE 类,接口
FIELD 成员变量
METHOD 成员方法
PARAMETER 方法参数
CONSTRUCTOR 构造器
LOCAL_VARIABLE 局部变量

@Retention

该注解可使用的值在java.lang.annotation.RetentionPolicy枚举类中

变量 描述
SOURCE 注解只作用在源码阶段,生成的字节码文件中不存在
CLASS 注解作用在源码阶段和字节码文字阶段,但运行阶段不存在,默认值是CLASS
RUNTIME 注解作用在源码阶段,字节码文件阶段以及运行阶段(开发常用)

注解解析

注解解析:判断是否存在注解,存在就解析出内容

相关的接口:

  • Annotaion : 注解的顶级接口,注解都是Annotation类型的对象
  • AnnotatedElement: 该接口定义了与注解解析相关的解析方法
返回类型 方法名 描述
Annotation[] getDeclaredAnnotations() 获得当前对象上使用的所有注解,返回注解数组
T getDeclaredAnnotation(Class <T> annotationClass) 根据注解类型获得对应注解对象
boolean isAnnotationPresent(Class<Annotation> annotationClass) 判断当前对象是否使用了指定的注解,若使用了则返回
  • 所有的类成分Class,Method,Field,Constructor都实现了AnnotatedElement接口,所以它们都有解析注解的作用

解析注解的Tips:

注解在哪个成分就先拿哪个成分对象

比如注解作用是成员方法,则要获得该成员方法对应的Method对象,再拿其注解

比如注解作用在类上,则要该类的Class对象,再拿注解

... 以此类推

范例:获取一个类中所有注解的信息

User.java

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface User{
    String id();
    String pasword() default "123456";
}

TestAnnotation.java

import org.junit.Test;

@User(id = "uni")
class Demo{
    @User(id ="java")
     public void test() {}
}

public class TestAnnotation{
    @Test
    public void parseClass(){
        Class userC = Demo.class;
        // 判断该类上是否存在注解
        if(userC.isAnnotationPresent(User.class)){
            User user = (User) userC.getDeclaredAnnotation(User.class);
            System.out.println(user.id());
            System.out.println(user.pasword());
        }
    }
}

运行结果

uni
123456

范例:获取类中注解的方法

    public void parseMethod() throws NoSuchMethodException {
        Class userC = Demo.class;
        Method method = userC.getDeclaredMethod("test");
        // 判断该类的test方法上是否存在注解
        if(method.isAnnotationPresent(User.class)){
            User user = (User) method.getDeclaredAnnotation(User.class);
            System.out.println(user.id());
            System.out.println(user.pasword());
        }
    }

注解应用场景

案例:模拟 Junit 框架

方法:使用反射机制获取类的所有方法并判断每个方法是否含有指定注解,若有则使用反射调用该方法

MyTest.java

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyTest {
}

TestAnnotation.java

import org.junit.Test;

import java.lang.reflect.Method;

public class TestAnnotation{
    @MyTest
    public void test1(){
        System.out.println("test1.");
    }
    public void test2(){
        System.out.println("test2.");
    }
    @MyTest
    public void test3(){
        System.out.println("test3.");
    }

    public static void main(String[] args) throws Exception{
        TestAnnotation t = new TestAnnotation();
        Class c = TestAnnotation.class;
        Method[] methods = c.getDeclaredMethods();
        for (Method method : methods) {
            if(method.isAnnotationPresent(MyTest.class)){
                method.invoke(t);
            }
        }
    }
}

运行结果

test1.
test3.

posted @ 2021-11-13 00:35  Unirithe  阅读(134)  评论(0)    收藏  举报