Java注解

元注解:

@Document :标记注解,注解信息包含到说明文档中


@Target:标识注解的目标:该注解用于方法、类、变量,可以有多个,类型为ElementType

            TYPE:表示类、接口、枚举声明

            FIELD:字段,包括枚举变量

            METHOD:方法

            PARAMETER:方法中的参数

           CONSTRUCOTOR:构造方法

           LOCAL_VARIABLE:本地变量

           MODULE:模块,Java9引入的

例如:

@Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD, ElementType.ANNOTATION_TYPE})

@Retention:标识注解信息保留到什么时候,取值只能有一个,类型为RetentionPolicy,如果不声明,默认为CLASS

          SOURCE:只在源码中保留,编译为字节码文件就会丢掉

          CLASS:保留到字节码文件中,但虚拟机加class文件加载到内存时不一定会在内存中保留

          RUNTIME:一直保留到运行时


 

@Inherited : 表示注解可以继承


注解可以定义参数,定义方式:在注解内定义一些方法,返回值表示参数类型,方法名为value,且只有一个参数时可以省略“value=”

要求:

1、注解内参数只能为:基本类型、String、Class、枚举、注解

2、可以在方法末尾加上默认值:default xxx,得是具体值,不能为null


案例 1:


import java.lang.annotation.*;

public class InheritDemo {

    @Inherited  //注解可以继承
    @Target(value = ElementType.TYPE) //注解用于类上,因为只有一个参数,可以省略 “value=”
    @Retention(RetentionPolicy.RUNTIME)
    static @interface Test{

    }
    @Test
    static class Base{

    }

    static class Child extends Base {  //继承注解

    }

    public static void main(String[] args) throws ClassNotFoundException {
        //判断Child目前有无Test.class注解,如果改为Class或者Source,就会返回false,因为运行时没有保留
        System.out.println(Class.forName(Child.class.getName()).isAnnotationPresent(Test.class));
    }

}

注解原理:

Annotation是一个接口,它表示注解。注解内部实现时,都是扩展的Annotation,annotationType()方法返回实际的注解

public interface Annotation {
   
    boolean equals(Object obj);
  
    int hashCode();

    String toString();

    //返回真正的注解类型
    Class<? extends Annotation> annotationType();
}

通过    public Annotation[][] getParameterAnnotations()返回方法参数的注解,每个参数对应一个一维数组。

DI案例:定义业务1和业务2,业务1依赖业务2,通过注解,把实例化交给容器实现。

//定义业务1
public class ServiceA {

  
    @SimpleInject
    private ServiceB serviceB;

    public void callB(){
        serviceB.action();
    }
}
//定义业务B
public class ServiceB {
    public void action(){
        System.out.println("i am b ,do action");
    }
}
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

//定义DI注解
@Target({ElementType.TYPE,ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface SimpleInject {
}

/**
 * DI工厂
 */
public class SimpleContainer {
    public static <T> T getInstance(Class<T> clazz){
        try{
            //工厂获取所需实例
            T obj = clazz.newInstance();
            //获取需要注入实例的成员变量
            Field[] fields = clazz.getDeclaredFields();
            //循环给所有需要注入的成员变量赋值
            for (Field field : fields){
                //如果标注有注解的成员变量,进行注入
                if (field.isAnnotationPresent(SimpleInject.class)){
                    //如果是私有变量,设置允许获取私有变量
                    if (!field.isAccessible()){
                        field.setAccessible(true);
                    }
                    //获取私有变量的Class对象
                    Class<?> fieldClazz = field.getType();
                    //给我们需要的类注入获取到的成员对象的实例
                    field.set(obj,getInstance(fieldClazz));
                }


            }
            //返回注入好的实例
            return obj;
        }catch (Exception e){
            throw new RuntimeException(e);
        }
    }
}

 

总结:

注解提高了Java语言的表达能力,有效实现了应用功能和底层功能的分离.业务和框架开发相分离,业务通过注解和库和框架写作

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值