Java注解系列之1st

16 篇文章 0 订阅
6 篇文章 1 订阅

岁月不居,时节如流,而立之年,忽焉将至

作为Android开发者,我们经常在项目中看到注解的身影(尤其以早期的EventBus和ButterKnife为甚),所以掌握它是非常有必要的。


Java注解

JDK1.5之后引入的注解

参考自:

注解的分类:

按照来源来分:

元注解:定义注解的注解,位于java.lang.annotation包下。

  1. @Target
  2. @Retention
  3. @Documented
  4. @Inherited
  5. @Repeatable(1.8)

自定义注解:JDK注解,第三方库注解,我们自己定义的注解

按照注解的时机(作用域)来划分:

  1. Source Code 注解
  2. 编译时注解
  3. 运行时注解
@Target

主要用于定义注解所使用的目标,其参数是ElementType枚举类。如果不设置该注解,意味着可以作用于任何目标。

@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();
}


下面来看一下其参数ElementType的内容:

ElementType说明版本
ElementType.TYPE适用于类,接口,注解,枚举1.5
ElementType.FIELD适用于属性(枚举常量)1.5
ElementType.METHOD适用于方法1.5
ElementType.PARAMETER适用于方法参数1.5
ElementType.CONSTRUCTOR适用于构造方法1.5
ElementType.LOCAL_VARIABLE适用于本地变量1.5
ElementType.ANNOTATION_TYPE适用于注解1.5
ElementType.PACKAGE适用于包1.5
ElementType.TYPE_PARAMETER适用于类型参数1.8
ElementType.TYPE_USE适用于类型1.8
ElementType.MODULE适用于模块9
ElementType.RECORD_COMPONENT记录Java预览版的特性(一般用不到)14
@Retention

为了更好地使用@Retention,首先要理解Retention的英文意思:保留

国内的很多开发者习惯性将该注解理解为:注解时机(生命周期)等。在实用性来讲,这种理解有助于我们使用该注解。
但是从Java语言的设计来讲,这样理解显然是有问题的(若喷请往他处)。

口说无凭,事实为证。具体请参考:Java Language Specification

Annotations may be present only in source code, or they may be present in the binary form of a class or interface. An annotation that is present in the binary form may or may not be available at run time via the reflection libraries of the Java SE Platform. The annotation type java.lang.annotation.Retention is used to choose among these possibilities.
(注解可能只被出现在源码中,也可能只出现在类或者接口的二进制形式(字节码即.class文件。另外出现在二进制形式的注解通过Java SE平台的反射库决定其在运行时可用或者不可用。@Retention这个注解就是用来在这些可能性中进行选择的))

理解一下这个过程:

Source Code

▼ ◁ Compiler

Class file

▼ ◁ JVM

Runtime

根据文档的描述,我们可以知道有三种情况:

  1. 源码中
  2. Class文件中
  3. Class文件中没有
    具体看一下源码:
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {
    /**
     * Returns the retention policy.
     * @return the retention policy
     */
    RetentionPolicy value();
}

真正的策略在RetentionPolicy中:

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文件中,但是运行时不会被虚拟机保留。默认行为
     */
    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.
     * 注解将会被编译器记录在Class文件中,同时在运行时被虚拟机保留。所以通过反射读取。
     *
     * @see java.lang.reflect.AnnotatedElement
     */
    RUNTIME
}

@Inherited

该注解所修饰的注解具有继承性.一般用不到

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

这里我们简单做个Demo:
首先声明一个注解:

import java.lang.annotation.Inherited;@Retention(RetentionPolicy.CLASS)
@Target(ElementType.TYPE)
@Inherited
public @interface HelloAnnotation {
    String name() default "";
    int value();
}


@HelloAnnotation(name = "Bertking",value = 1)
public class Hello{
    
}

// 子类,将会继承其父类的注解
public class SubClass extends Hello{
    
}

@Documented

该注解是为了在生成Javadoc时加上注释,一般开发也用不到。

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

@Repeatable是Java8为了解决同一个注解不能重复用在同一目标上的问题。

一般情况下,将会根据注解中参数的内容来做不同的工作。这里做个Demo

// 可重复注解的容器
public @interface RepeatableAnnoContainer {
    RepeatableAnno[] value();
}

// 可重复注解
@Repeatable(RepeatableAnnoContainer.class)
public @interface RepeatableAnno {
  String value() default "";
}

// 实际应用
@RepeatableAnno()
@RepeatableAnno("King")
@RepeatableAnno("Bert")
public class Demo{
    
}

最后贴上Repeatable的源码:


@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();
}

更多的内容,请移步至:Github-AnnotationsExplorer

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值