第十八次总结 注解

  1. 什么是注解?
  2. 什么是元注解?
  3. 通过注解的方式实现自动注入?

1.什么是注解?

注解是程序的一部分
@Override 限定方法必须是重写的方法
@Deprecated 标记一个已经过时的方法
@SuppressWarnings("rawtypes") 忽略警告

 

自定义一个注解

 

 

 


2.什么是元注解?

 

元注解:用在注解中的注解


@Target 用来定义注解的使用范围
ElementType.ANNOTATION_TYPE 用在注解中
PACKAGE      用在包中
TYPE         用在类型上
CONSTRUCTOR   用在构造方法上
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();
    }
}

 

输出结果:

 

posted @ 2020-08-13 14:57  Zc小白  阅读(128)  评论(0)    收藏  举报