注解入门

注解入门

注解和注释

注释是给人看的,注解是给机器(编译器,虚拟机)看的。

注解的概念

注解是一个标识,或者说是标签。

注解是一系列元数据,它提供数据用来解释程序代码,但是注解并非是所解释的代码本身的一部分。注解对于代码的运行效果没有直接影响。
注解有许多用处,主要如下:
- 提供信息给编译器: 编译器可以利用注解来探测错误和警告信息
- 编译阶段时的处理: 软件工具可以用来利用注解信息来生成代码、Html文档或者做其它相应处理。
- 运行时的处理: 某些注解可以在程序运行的时候接受代码的提取

注解长什么样,怎么用,如何生效,效果是什么

需要提前说的是,单单为一个类/一个方法/一个变量/等添加注解,完全不会影响代码地运行。重要的是程序对注解进行提取,根据提到的注解做一定的事情才会起作用(提取以及响应可以由编译器、框架代码或者开发者自己处理,一般框架只会处理框架定义的注解,开发人员也只会处理自己定义的注解)。

先来一个系统定义的 : Override

//注解的定义是这样的
@Target(ElementType.METHOD)//标明该注解的使用对象是方法
@Retention(RetentionPolicy.SOURCE)//标明该注解的生效场景是在源码中
    public @interface Override {
}

//注解的使用是这样的
@Override
public void methodDefineInParentType(){
     // your code...
}

// 如何生效
// 前面注释说到了该注解仅在源码中生效,由编译器识别注解,并且给予开发者提示

// 效果是什么
// 如果父类定义了该方法,则没有什么效果,仅用于提示。如果父类没有该方法,则编译器给出提示,并且编译器不允许编译通过(其实编译器也可以允许编译通过,即使通过,也不影响代码的运行效果)

再来一个自定义的:

/**
 * 自定义注解跟系统定义的注解都一样,可以使用元注解对注解进行说明
 * Target = Element.TYPE 说明了该注解可以作用在类和接口上
**/
@Target(ElementType.TYPE)//可以用在类、接口、枚举类上
@Retention(RetentionPolicy.RUNTIME)//保留到运行时
public @interface UselessAnnotation{
        String stringValue() default "test";//添加了一个成员变量,变量的默认值是test
}

//使用
@UselessAnnotation(stringValue = "helloWorld")
public class MainActivity extends AppCompatActivity {
        ...

        //1. 判断MainActivity.class上是否存在特定类型的注解
        //2. 获取MainActivity.class上是特定类型的注解
        //3. 获取注解的变量值并且赋值给一个textView
        if (MainActivity.class.isAnnotationPresent(UselessAnnotation.class)) {
            UselessAnnotation annotation = MainActivity.class.getAnnotation(UselessAnnotation.class);
            String string = annotation.stringValue();
            textView.setText(string);
        }  

        ...
}

元注解

作用在注解上的注解叫做元注解。
Java提供的元注解有五种:
- @Retention : 设置保留期
- @Documented :设置是否在javaDoc中呈现
- @Target :设置注解的作用对象
- @Inherited ://设置注解可被继承
- @Repeatable ://设置注解可重复

@Retention

retention用于说明注解保留的时间

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {
    /**
     * Returns the retention policy.
     * @return the retention policy
     */
    RetentionPolicy value();
}

public enum RetentionPolicy {
    /**
     * Annotations are to be discarded by the compiler.
     * 注解只在源码中存在,保留到编译之前,在编译时就扔掉了
     */
    SOURCE,

    /**
     * Annotations are to be recorded in the class file by the compiler
     * but need not be retained by the VM at run time.  This is the default
     * behavior.
     * 保留到编译器进行编译时,编译时注解可以在编译时被注解处理器进行处理,然后插入生成代码之类的(这也是很多编译时注解框架使用的方法)。
     * 但是不会保留到运行时
     */
    CLASS,

    /**
     * Annotations are to be recorded in the class file by the compiler and
     * retained by the VM at run time, so they may be read reflectively.
     * 保留到Java字节码文件中,并且被加载到虚拟机中,故而可以在运行时通过反射获取
     *
     * @see java.lang.reflect.AnnotatedElement
     */
    RUNTIME
}

@Documented

顾名思义,这个元注解肯定是和文档有关。它的作用是能够将注解中的元素包含到 Javadoc 中去

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Documented {
}

@Target

Target 是目标的意思,@Target 指定了注解运用的地方。

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Target {
    /**
     * Returns an array of the kinds of elements an annotation type
     * can be applied to.
     * @return an array of the kinds of elements an annotation type
     * can be applied to
     */
    ElementType[] value();
}

@Target 有下面的取值

  • ElementType.ANNOTATION_TYPE 可以作用于注解
  • ElementType.CONSTRUCTOR 可以作用于构造方法
  • ElementType.FIELD 可以作用于属性
  • ElementType.LOCAL_VARIABLE 可以作用于局部变量
  • ElementType.METHOD 可以作用于方法
  • ElementType.PACKAGE 可以作用于包
  • ElementType.PARAMETER 可以作用于参数
  • ElementType.TYPE 可以作用于一个类型,比如类、接口、枚举

@Inherited

如果一个超类被 @Inherited 注解过的注解进行注解的话,那么如果它的子类没有被任何注解应用的话,那么这个子类就继承了超类的注解。

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Inherited {
}

@Repeatable

@Repeatable 是 Java 1.8 才加进来的,所以算是一个新的特性。
什么样的注解会多次应用呢?通常是注解的值可以同时取多个(这似乎可以被数组取代)。暂时不明白它的独特点。

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Repeatable {
    /**
     * Indicates the <em>containing annotation type</em> for the
     * repeatable annotation type.
     * @return the containing annotation type
     */
    Class<? extends Annotation> value();
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值