《Java基礎知識》Java注解"@"詳解


Java注解含義:

Java注解,顧名思義,注解,就是對某一事物進行添加注釋說明,會存放一些信息,這些信息可能對以后某個時段來說是很有用處的。
Java注解又叫java標注,java提供了一套機制,使得我們可以對方法、類、參數、包、域以及變量等添加標准(即附上某些信息)。且在以后某個時段通過反射將標注的信息提取出來以供使用。

 

樣例(實現一個自己的注解):

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

@Target(value = {ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotaion {
    String value();
}
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(value = {ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyFieldAnnotaion {
    String value();
    String type();
    String lengths();
}
import java.io.Serializable;

@MyAnnotaion("student")
public class Student implements Serializable {

    private static final long serialVersionUID = 1L;

    @MyFieldAnnotaion(value = "1",type = "int",lengths = "10")
    String id;
    @MyFieldAnnotaion(value = "蕾蕾",type = "String" ,lengths = "200")
    String name;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Student{" +
                "id='" + id + '\'' +
                ", name='" + name + '\'' +
                '}';
    }
}
import org.apache.poi.ss.formula.functions.T;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;

/**
 * 通過反射獲取注解
 */
public class AnnotaionDemo {
    public static void main(String[] args) throws Exception {
        Class<T> clazz = (Class<T>) Class.forName("demo.knowledgepoints.annotation.Student");
        //判斷注解是否存在
        if(clazz.isAnnotationPresent(MyAnnotaion.class)){
            System.out.println("存在注解:MyAnnotaion");
        }

        //獲取注解列表
        Annotation[] annotaions = clazz.getAnnotations();
        for (int i = 0; i < annotaions.length; i++) {
            System.out.println("注解:"+annotaions[i]);
        }

        //獲取注解內容
        MyAnnotaion myAnnotaion = clazz.getAnnotation(MyAnnotaion.class) ;
        System.out.println("注解的值為:"+myAnnotaion.value());

        //獲取方法上的注解內容
        Field field = clazz.getDeclaredField("id");

        //方法上注解是否存在
        field.isAnnotationPresent(MyFieldAnnotaion.class);
        //方法注解列表
        field.getAnnotations();

        //獲取方法上的注解內容
        MyFieldAnnotaion myFieldAnnotaion = field.getAnnotation(MyFieldAnnotaion.class);
        System.out.println("value:"+myFieldAnnotaion.value()+"; type:"+myFieldAnnotaion.type()+"; lengths:"+myFieldAnnotaion.lengths());
    }
}

運行結果:

根據這個案例:

1. 注解實現需要關鍵字:@interface;

2. 在注解上我們還使用了注解 @Target,@Retention。這些被稱為元注解,

   Java中元注解有四個: @Retention @Target @Document @Inherited;

   @Retention:注解的保留位置

        @Retention(RetentionPolicy.SOURCE)   //注解僅存在於源碼中,在class字節碼文件中不包含

     @Retention(RetentionPolicy.CLASS)     // 默認的保留策略,注解會在class字節碼文件中存在,但運行時無法獲得,

     @Retention(RetentionPolicy.RUNTIME)  // 注解會在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) ///包

    @Document:說明該注解將被包含在javadoc中

    @Inherited:說明子類可以繼承父類中的該注解

3. 直接里面可以寫方法:String value(); 

   外部使用注解可以將值寫入,后續可以拿到該值進行使用。

可以提供默認值: String value() default "花花";   

 

修改 AnnotaionDemo 的方法實現一個常用功能,通過注解將值注入實體類中: 

import org.apache.poi.ss.formula.functions.T;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

/**
 * 通過反射獲取注解
 */
public class AnnotaionDemo {
    public static void main(String[] args) throws Exception {
        Student student = (Student) getbean("demo.knowledgepoints.annotation.Student");
        System.out.println(student);
    }

    public static Object getbean(String className) throws Exception{
        Class<T> clazz = (Class<T>) Class.forName(className);
        //判斷注解是否存在(該注解被當成標記使用)
        if(!clazz.isAnnotationPresent(MyAnnotaion.class)){
            throw new Exception("該類缺失注解“MyAnnotaion”,不能通過反射獲取bean");
        }

        //創建實體類
        Object object = clazz.newInstance();

        Field[] fields = clazz.getDeclaredFields();
        for (int i = 0; i < fields.length; i++) {
            //獲取字段名
            String name = fields[i].getName();

            //過濾序列
            if (name.equals("serialVersionUID")) {
                continue;
            }

            //組裝SET方法
            Class<?> type = clazz.getDeclaredField(name).getType();

            // 首字母大寫
            String replace = name.substring(0, 1).toUpperCase()
                    + name.substring(1);
            Method setMethod = clazz.getMethod("set" + replace, type);
            //獲取字段值
            Field field = clazz.getDeclaredField(name);
            MyFieldAnnotaion myFieldAnnotaion = field.getAnnotation(MyFieldAnnotaion.class);
            String value = myFieldAnnotaion.value();
            //執行set方法
            if (value != null && !"".equals(value)) {
                // ---判斷讀取數據的類型(判斷部分類型)
                if (type.isAssignableFrom(String.class)) {
                    setMethod.invoke(object, value);
                } else if (type.isAssignableFrom(int.class)
                        || type.isAssignableFrom(Integer.class)) {
                    setMethod.invoke(object, Integer.parseInt(value));
                } else if (type.isAssignableFrom(Double.class)
                        || type.isAssignableFrom(double.class)) {
                    setMethod.invoke(object, Double.parseDouble(value));
                } else if (type.isAssignableFrom(Boolean.class)
                        || type.isAssignableFrom(boolean.class)) {
                    setMethod.invoke(object, Boolean.parseBoolean(value));
                }
            }
        }
        return object;
    }
}

運行結果:

案例中使用了反射:反射詳解:https://www.cnblogs.com/jssj/p/11723910.html

總結語:注解功能在框架開發中被廣泛使用:例如Spring,MyBatis等。注解的出現大大的減少了開發工作中的開發工作量。

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM