注解及自定义注解

目录

  1. 初识注解
  2. 自定义注解
  3. 查看某类上是否标有某注解isAnnotationPresent
  4. 使用自定义注解
  5. 解析自定义注解
  6. 利用注解自己实现一个简单的spring框架,实现IOC和DI

初识注解

import java.lang.annotation.*;

/**
 *所有的注解默认继承自Annotation注解(本质是一个继承Annotaion的接口)

 * 4个元注解(修饰注解的注解,且只能修饰注解,元注解的target=ElementType.ANNOTATION_TYPE):
 * @Target @Retention @Inherited @Documented
 * @Target:允许标注的位置 
 * ElementType.TYPE:类上
 * ElementType.FIELD:属性上
 * ElementType.METHOD:方法上
 * @Retention:注解的保留策略(只有保留到运行时的注解才可以通过反射获取)
 * RetentionPolicy.SOURCE:仅存在于源文件里(不可以通过反射读取)
 * RetentionPolicy.CLASS:存在到class字节码文件里(不可以通过反射读取)
 * RetentionPolicy.RUNTIME:保留到运行时候(可以通过反射读取)
 * * 源代码文件---编译---》字节码文件--加载----》JVM
 * * SOURCE               CLASS             RUNTIME
 * @Inherited:注解是否可以被继承,父类标有的注解如果可继承,那么他的子类自动继承注解(接口和接 
 * 口实现类不支持继承注解,只支持父类和子类)
 * @Documented:此注解是否能被文档所记录
 */
@Target({ElementType.TYPE, ElementType.FIELD, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface MyAnnotation {
    /**
     * 自定义注解用:@interface标识
     * >>属性都是默认 public static final修饰(myValue)
     * >>方法都是默认 public abstract修饰
     * >>方法设有默认值的,使用注解不用必须指定值,没有设置默认值必须指定
     * >>方法必须有返回值,但是没有参数,使用的时候直接把参数传给方法名字即可     
     * >>返回值必须是以下6种类型
     * 1.基本数据类型
     * 2.String类型
     * 3.Class类型
     * 4.注解类型
     * 5.枚举类型
     * 6.一维数组类型,但是数组内部的元素都必须是以上5种类型
     **/
    String myValue = "test";

    int getNum();//1.基本数据类型

    String name() default "";//2.String类型(有默认值)

    Class<? extends UserFather> getClazz();//3.Class类型

    Override getAnnotation();//4.注解类型

    MyColorEnum getColorEnum();//5.枚举类型

    String[] strArr();//6.一维数组类型,但是数组内部的元素都必须是以上5种类型

}

 

查看某类上是否标有某注解isAnnotationPresent

public class My {
    public static void main(String[] args) {
        Class<My1> my1Class = My1.class;
        boolean annotationPresent = my1Class.isAnnotationPresent(Documented.class);
        System.out.println("annotationPresent = " + annotationPresent);
    }
}

自定义注解

@Target({ElementType.TYPE, ElementType.FIELD, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface MyAnnotation {
    String name() default "";

    String value();

}

 

 

使用自定义注解

public class User extends UserFather {
    @MyAnnotation("张三")//不指定方法名:则默认是给value()方法指定的
    private String userName;
    private String password;
    private Integer age;

    @MyAnnotation(value = "张三", name = "三")
    public void test() {
    }
//get set .......

}

public class My {
    public static void main(String[] args) {
        Class<My1> my1Class = My1.class;
        boolean annotationPresent = my1Class.isAnnotationPresent(Documented.class);
        System.out.println("annotationPresent = " + annotationPresent);
    }
}

 

解析自定义注解

@Test
    public void test() throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException {
        /**
         *  解析注解值的前提是反射:
         *  获取类上的注解:需要首先获取 Class--->clazz.getDeclaredAnnotation(MyAnnotation.class)
         *  获取field上的注解:需要想先获取到field -->userNameField.getDeclaredAnnotation(MyAnnotation.class)
         *  获取method上的注解:需要想先获取到method--->testMethod.getAnnotation(MyAnnotation.class)

         * 获取到注解后直接--》注解实例.方法名就可以获取对一个方法的返回值了
         */

        Class<?> clazz = Class.forName("com.blog.annotation.test.User");//获取Class
        MyAnnotation classMyAnnotation = clazz.getDeclaredAnnotation(MyAnnotation.class);//获取类上的注解
        System.out.println(classMyAnnotation.value());//直接调用注解里的方法获取值
        System.out.println(classMyAnnotation.name());
        Field userNameField = clazz.getDeclaredField("userName");
        MyAnnotation fieldMyAnnotation = userNameField.getDeclaredAnnotation(MyAnnotation.class);//获取field的上的注解
        System.out.println(fieldMyAnnotation.value());
        System.out.println(fieldMyAnnotation.name());
        Method test = clazz.getDeclaredMethod("test", null);
        MyAnnotation methodMyAnnotation = test.getAnnotation(MyAnnotation.class);//获取方法上的注解
        System.out.println(methodMyAnnotation.value());
        System.out.println(methodMyAnnotation.name());
    }
 

利用注解自己实现一个简单的spring框架,实现IOC和DI

(即类由代理创建,属性由代理注入)
 

//1.自定义注解类

@Target({ElementType.CONSTRUCTOR})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface MyAnnotation {
    String[] value();
}
//2.使用注解的类

import java.util.Date;

public class User {
    private String userName;
    private String password;
    private String age;
    private User2 user2;
    private Date myDate;
    private Character character;

    @MyAnnotation({"张三三", "admin", "14", "李四四", "20190526", "2"})
    public User() {
    }

    get和set......
}

//3.实现IOC和DI的核心类

public class MySpring {
    public Object getBeanByClassName(String name, String dateFormat) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException, ParseException {
        Class<?> clazz = Class.forName(name);//获取class
        Object obj = clazz.newInstance();//创建对象
        Constructor<?> cons = clazz.getDeclaredConstructor();//根据class获取构造方法
        MyAnnotation myAnnotation = cons.getDeclaredAnnotation(MyAnnotation.class);//获取构造方法上的注解
        String[] values = myAnnotation.value();//获取注解里面的值
        Field[] fields = clazz.getDeclaredFields();//获取fields
        //给创建的对象属性赋值
        for (int i = 0; i < fields.length; i++) {
            fields[i].setAccessible(true);
            Class<?> type = fields[i].getType();
            if (Date.class.isAssignableFrom(type)) {//日期类型
                SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
                fields[i].set(obj, sdf.parse(values[i]));
            } else if (Character.class.isAssignableFrom(type)) {//Character类型
                char[] chars = values[i].toCharArray();
                fields[i].set(obj, chars[0]);
            } else {//八大包装类型)或者类对象(此对象必须有一个String类型参数的构造方法的类对象)
                fields[i].set(obj, fields[i].getType().getDeclaredConstructor(String.class).newInstance(values[i]));
            }
        }
        return obj;
    }
}

//4.测试类

public class TestAnnotation {
    @Test
    public void test() throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException, ParseException {
        MySpring mySpring = new MySpring();
        User user = (User) mySpring.getBeanByClassName("com.blog.annotation.test.User", "yyyyMMdd");
        System.out.println(user);

    }
}

//5.运行结果

{
	"age":"14",
	"character":"2",
	"myDate":1558800000000,
	"password":"admin",
	"user2":{
		"name":"李四四"
	},
	"userName":"张三三"
}

 

运行结果:

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值