浅析---注解

1注解

1.1概述
注释:// // / */ <%– –%>给开发人员看的。
注解:给机器(编译器、类加载器、JVM)看的
使用注解的格式: @注解名称(属性名1=属性值1,…,属性名n=属性值n)
作用:在一些开发的场景中实现轻量级的配置。
副作用是:增加了耦合度
注意:JDK API文档中将注解误译成了注释。

1.2常见的注解
1.2.1 @Override表示重写父类的方法
在编译时验证以下几点信息:修饰符范围>=父类的方法;方法的签名和返回值也得一样。
@Override
public boolean equals(Object obj) {
return super.equals(obj);
}

1.2.3 @SuppressWarnings:抑制编译器显示警告信息的
比如:@SuppressWarnings(“unused”)抑制编译器显示未被使用的警告信息

1.3自定注解的开发流程:
定义注解(创建一个注解类)->反射注解->使用注解

1.4 定义注解

1.4.1自定义注解的基本格式:
public @interface 注解名称 {}
比如:public @interface Anno1 {}
底层帮我们自动实现java.lang.annotation.Annotation接口

1.4.2源生注解:用于修饰注解的注解。

    @Target(ElementType.XXX):表示被修饰的注解能够在什么元素(类和接口,方法、属性、成员变量、构造方法..)上使用
    @Retention(RetentionPolicy.SOURCE):表示注解的保留域。
    @Documented:表示生成的javadoc中是否保留注解的信息。

1.4.3注解中的属性
1、注解属性的定义和接口中方法的定义类似,默认是public,所以public可以省略。public String name();
2、属性定义可以通过default为属性指定默认值,指定默认值的属性,在注解使用时,可以为之赋值,也可以不为之赋值。如果不通过default为属性指定默认值,在注解使用必须使用该属性并且还得为之赋值。
3、如果在一个注解中,某个属性必须使用并且需要给他赋值注解才能被使用,可以在属性定义时不使用default指定默认值。
4、注解中有一个特殊的属性value,如果仅为该属性赋值,”value=”可以省略掉,但是如何和其他属性同时赋值,“value=”则不能省略。和该属性的类型无关,仅和名称有关。
5、属性的类型可以八种基本数据类型、Class、枚举、String等,以及以上类型的一维数组。
6、如果属性是一维数组,在赋值值如果仅有一个值“{}”才可以省略。

1.4.4.1@Target(ElementType.XXX):
表示被修饰的注解能够在什么元素(类和接口,方法、属性、成员变量、构造方法..)上使用

***CONSTRUCTOR构造方法声明
FIELD 字段声明(包括枚举常量)
LOCAL_VARIABLE 局部变量声明
METHOD方法声明
PACKAGE包声明
PARAMETER参数声明
TYPE类、接口(包括注解类型)或枚举声明*


@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}  //表示该注解只能被用在方法上。
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {
    RetentionPolicy value();
}  //Retention注解只能被用在注解上。

1.4.4.2
@Retention(RetentionPolicy.SOURCE)
表示注解的保留域。

*补充:
编译器 类加载 JVM
.java –>.class –>被加载到内存中->运行*

RetentionPolicy.SOURCE:给编译器看,编译器编译后该类型的注解就被丢弃掉了。(生成.class字节码文件中,将不再存在该类型的注解)
RetentionPolicy.CLASS:字节码级别的,给类加载器看的,在类被加载时做一些引导相关的一些操作。编译器编译保留,类加载器加载时使用,加载后丢弃掉。
RetentionPolicy.RUNTIME:给JVM看的,编译器编译后保留,类加载器加载保留,在运行时,JVM使用。
通常自定义的注解都是使用该保留域,在程序运行时反射注解中的信息,并根据属性的值做相关的操作。

1.4.4.3@Documented:
表示生成的javadoc中是否保留注解的信息。如何使用注解
1.4.5如何反射注解
@Retention(RetentionPolicy.RUNTIME)
如果注解想要被反射,注解的保留域必须设置为RUNTIME保留域。

jdk中提供的注解反射接口:AnnotatedElement,提供了以下几个方法:

<T extends Annotation> T getAnnotation(Class<T> annotationClass)  
如果存在该元素的指定类型的注解,则返回这个注解,否则返回 null
 Annotation[]   getAnnotations() 
  返回此元素上存在的所有注解。
 Annotation[]   getDeclaredAnnotations() 
     返回直接存在于此元素上的所有注解。
 boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) 
   如果指定类型的注解存在于此元素上,则返回 true,否则返回 false。
已知该接口的实现类:Class, Constructor,Field, Method, Package   以上这些类的对象均可调用反射的相关方法。

案例如下:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface PoliceLevel {
    public String level() default "";
}
@PoliceLevel(level="大队长")
public class Police {
    public void getMoney(){
        System.out.println("敬个礼,您违章了,罚款200....");
    }
    public static void main(String[] args) {
        /*Police pc = new Police();
        pc.getMoney();*/
        Polic pc = new Polic();
        pc.getMoney();
        //判断真假
        if(pc.getClass().isAnnotationPresent(PoliceLevel.class)){
            //真交警
            PoliceLevel pl = pc.getClass().getAnnotation(
                    PoliceLevel.class);
            //获取注解中属性的值
            String level = pl.level();
            if("协警".equals(level)){
                System.out.println("哥们抽个烟,偷么给50,不需要开票");
            }else if("交警".equals(level)){
                System.out.println("给200元...");
            }else if("大队长".equals(level)){
                System.out.println("给2000,麻烦给开一个免罚牌");
            }
        }else{
            System.out.println("抽一顿,送到警察局...");
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值