Java中的註解--個人總結

2020-08-14 01:04:38

Java中的註解

  1. 什麼是註解?
  2. 什麼是元註解?
  3. 通過註解的方式實現自動注入

1.什麼是註解?

註解是程式的一部分
@Override 限定方法必須是重寫的方法
@Deprecated 標記一個已經過時的方法
@SuppressWarnings(「型別參數」)忽略警告
自定義一個註解
在这里插入图片描述

2.什麼是元註解?

元註解:用在註解中的註解
@Target 用來定義註解的使用範圍
ElementType.ANNOTATION_TYPE 用在註解中
PACKAGE 用在包中
TYPE 用在型別上
CONSTRUCOR 用在構造方法上
FIELD 用在屬性上
METHOD 用在方法上

@Retention 用來定義註解的存在時間
RetentionPolicy.SOURCE 註解只存在於原始碼中,編譯成class的時候會丟棄註解
RetentionPolicy.CLASS 註解存在於class檔案中,在載入到JVM的時候會丟棄註解
RetentionPolicy.RUNTIME 註解在程式執行中依然存在

@Documented 註解文件化

@Inherited 是否能被子類自動繼承

3.通過註解的方式實現自動注入?

MyTest

import java.lang.annotation.*;

/**
 * 自定義一個註解
 * 註解 Annotation
 */
@Target({ElementType.METHOD,ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyTest {

     String value();

}

Teacher

public class Teacher {

    @MyTest("張三")
    private String name;


    public void teachJava(){
        System.out.println(name+"在教Java課");
    }

    @Override
    public String toString() {
        return "Teacher{" +
                "name='" + name + '\'' +
                '}';
    }
}

AutoCreate

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

/**
 * 自定義建立物件的註解
 */
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface AutoCreate {

}

AnnotationUtil

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

/**
 * 自定義註解的處理工具
 */
public class AnnotationUtil {


    //解析obj物件的註解
    public static void initData(Object obj){
        try {
            //獲得obj物件的Class物件
            Class c = obj.getClass();
            //獲得name屬性物件
            Field name = c.getDeclaredField("name");
            //獲得name屬性上的MyTest註解物件
            MyTest an = name.getAnnotation(MyTest.class);
            //獲得註解中的value值
            String value = an.value();

            //將註解中的值設定給屬性
            name.setAccessible(true);
            name.set(obj,value);

        }catch (Exception ef){
            ef.printStackTrace();
        }

    }
}

AutoCreateUtil

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;

public class AutoCreateUtil {

    public static void init(Object obj){
        try {
            //拿到Manager類的Class物件
            Class c = obj.getClass();
            //獲得Manager類中的teacher屬性
            Field f = c.getDeclaredField("teacher");
            //獲得f變數的型別的Class物件[Teacher類的Class物件]
            Class c2 = f.getType();
            //獲得Teacher類的無參構造方法
            Constructor con = c2.getDeclaredConstructor();
            //範例化物件
            Object teacher = con.newInstance();
            //處理Teacher的MyTest註解
            AnnotationUtil.initData(teacher);

            //將teacher物件作爲f的值
            f.setAccessible(true);
            f.set(obj,teacher);

        }catch (Exception ef){
            ef.printStackTrace();
        }
    }

}

Teachertest

public class Teachertest {
    public static void main(String[] args) {
        Teacher t = new Teacher();
        //通過註解的方式設定屬性的值
        AnnotationUtil.initData(t);
        System.out.println(t);
    }
}

輸出結果:
在这里插入图片描述

如何在多個屬性中設定指點屬性?

Manager

public class Manager {

    @AutoCreate
    private Teacher teacher;
    @AutoCreate
    private Book book;
    @AutoCreate
    private Book book2;

    public void teach(){
        System.out.println(book);
        teacher.teachJava();
        System.out.println(book2);
    }

}

Book

public class Book {
    private String name;

    public Book() {
        name="java";
    }

    @Override
    public String toString() {
        return "Book{" +
                "name='" + name + '\'' +
                '}';
    }
}

AutoCreateUtil2

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;

public class AutoCreateUtil2 {

    public static void init(Object obj){
        try {
            //拿到Manager類的Class物件
            Class c = obj.getClass();


            Field[] fs = c.getDeclaredFields();
            for(Field f:fs){
                AutoCreate ac = f.getAnnotation(AutoCreate.class);
                if(ac!=null){
                    //獲得f變數的型別的Class物件[Teacher類的Class物件]
                    Class c2 = f.getType();
                    //獲得Teacher類的無參構造方法
                    Constructor con = c2.getDeclaredConstructor();
                    //範例化物件
                    Object obj2 = con.newInstance();
                    //將teacher物件作爲f的值
                    f.setAccessible(true);
                    f.set(obj, obj2);

                    if(f.getName().equals("teacher")){
                        AnnotationUtil.initData(obj2);

                    }
                }
            }
        }catch (Exception ef){
            ef.printStackTrace();
        }
    }

}

ManagerTest

public class ManagerTest {
    public static void main(String[] args) {
        Manager m = new Manager();

        AutoCreateUtil2.init(m);

        m.teach();
    }
}

輸出結果
在这里插入图片描述