Android Annotation ——XArch

  注解并不是第一次看到,类似于见过最多的 @Override 

【遇】

  BaseActivity中实现了 IGetPageName 接口,接口中 定义了 getPageName方法,添加 @PageName 注解,MainActivity中重写BaseActivity中的 getPageName 方法并设置返回值,这里达到了返回值只能设置为 PageName枚举中值的效果,而枚举使用静态常量+@StringDef 的方法定义。

@PageName 自定义注解,@StringDef (androidx.annotation包内)

BaseActivity.java

IGetPageName.java

PageName.java

 

 MainActivity.java

 

【问】

注解是什么,注解有什么作用?

在什么情况下会想到要使用注解?

 

【知】

参考博文:Java Annotation认知(包括框架图、详细介绍、示例说明) - 如果天空不死 - 博客园 (cnblogs.com)

1、 Java Annotation是JDK5.0引入的一种注释机制

2、我对于Annotation的理解

  

  ElementType、RetentionPolicy是枚举,Annotation是一个接口。然后我们由他们创建新的Annotation注解。新的注解,就是通过实现 Annotation的接口,然后再通过@Target、@Retention注解分别来指定ElementType、RetentionPolicy的值,结构图中1..n表示@Target可以指定多个枚举值(用来只能注解可以修饰的位置),而@Retention注解就只能指定一个枚举值(表示注解作用域,保留到的位置)。

  ①@Target本身也是注解,那么上面说注解创建时就要通过@Target来修饰Target的注解。所以存在以下代码

  

 ⭐为什么@Target能够修饰 Target Annotation?不是还在创建阶段吗

  有关于这个问题,我还没有答案。有人回答我说,就像递归,自己调用自己。对哇,递归,我以前为什么没有问,函数为什么能够自己调用自己?(从网上我得出的理解时,方法定义并不分配内存,而是相当于存储一个方法的指针,调用的时候再去执行具体的方法,所以当它调用自己的时候,它早就已经告诉编译器,它存在了。为什么函数能递归调用自己? - 知乎 (zhihu.com)

  除了@Target修饰Target,还存在@Target修饰 Retention 创建,@Retention修饰Target创建,这或许有点像在A函数里面调用B函数,B函数里面调用A函数。

  很难解释,那么是否可以跳过Target 创建,把@Target单纯看做成对该注解的注解。即我们只需要知道 @Target 只能修饰 ANNOTATION_TYPE(像这种只能修饰注解的注解称为元注解),JDK提供了一系列其他的注解,我们可通过注解上方的注解,了解这个注解的作用域和作用。

 

  ②ElementType枚举值以及说明

 

 

   ③RetentionPolicy的枚举值及说明

 

  ④元注解:修饰注解的注解,以下四个

@Documented  -- @Documented 所标注内容,可以出现在javadoc中。若不设置默认为否
@Inherited   -- @Inherited只能被用来标注“Annotation类型”,它所标注的Annotation具有继承性。就是使用该Annotation的类的子类也自动继承该父类的注解。若不设置默认为否
@Retention   -- @Retention只能被用来标注“Annotation类型”,而且它被用来指定Annotation的RetentionPolicy属性。若不设置默认为RetentionPolicy.CLASS
@Target      -- @Target只能被用来标注“Annotation类型”,而且它被用来指定Annotation的ElementType属性。若不设置默认为可作用域任何地方
@Repeatable  -- @Repeatable(重复) 用于声明标记的注解为可重复类型注解,可以在同一个地方多次使用

 

  ⑤其他注解

@SuppressWarnings -- @SuppressWarnings 所标注内容产生的警告,编译器会对这些警告保持静默。
@Deprecated  -- @Deprecated 所标注内容,不再被建议使用。

 

3、kotlin中的Annotation 有什么不同

  ①元注解不同 @Documented改成 @MustBeDocumented

去掉了@Inherited(查看:Inherited annotations and other reflections enchancements - Support - Kotlin Discussions (kotlinlang.org)

  ②ElementType名对应AnnotationTarget,RetentionPolicy名对应AnnotationRetention

  ③@Retention的默认值不同,Java中默认值为 RetentionPolicy.CLASS,Kotlin中是AnnotationRetention.RUNTIME

package kotlin.annotation

import kotlin.annotation.AnnotationTarget.*

/**
 * Contains the list of code elements which are the possible annotation targets
 */
public enum class AnnotationTarget {
    /** Class, interface or object, annotation class is also included */
    CLASS,
    /** Annotation class only */
    ANNOTATION_CLASS,
    /** Generic type parameter */
    TYPE_PARAMETER,
    /** Property */
    PROPERTY,
    /** Field, including property's backing field */
    FIELD,
    /** Local variable */
    LOCAL_VARIABLE,
    /** Value parameter of a function or a constructor */
    VALUE_PARAMETER,
    /** Constructor only (primary or secondary) */
    CONSTRUCTOR,
    /** Function (constructors are not included) */
    FUNCTION,
    /** Property getter only */
    PROPERTY_GETTER,
    /** Property setter only */
    PROPERTY_SETTER,
    /** Type usage */
    TYPE,
    /** Any expression */
    EXPRESSION,
    /** File */
    FILE,
    /** Type alias */
    @SinceKotlin("1.1")
    TYPEALIAS
}

/**
 * Contains the list of possible annotation's retentions.
 *
 * Determines how an annotation is stored in binary output.
 */
public enum class AnnotationRetention {
    /** Annotation isn't stored in binary output */
    SOURCE,
    /** Annotation is stored in binary output, but invisible for reflection */
    BINARY,
    /** Annotation is stored in binary output and visible for reflection (default retention) */
    RUNTIME
}

/**
 * This meta-annotation indicates the kinds of code elements which are possible targets of an annotation.
 *
 * If the target meta-annotation is not present on an annotation declaration, the annotation is applicable to the following elements:
 * [CLASS], [PROPERTY], [FIELD], [LOCAL_VARIABLE], [VALUE_PARAMETER], [CONSTRUCTOR], [FUNCTION], [PROPERTY_GETTER], [PROPERTY_SETTER].
 *
 * @property allowedTargets list of allowed annotation targets
 */
@Target(AnnotationTarget.ANNOTATION_CLASS)
@MustBeDocumented
public annotation class Target(vararg val allowedTargets: AnnotationTarget)

/**
 * This meta-annotation determines whether an annotation is stored in binary output and visible for reflection. By default, both are true.
 *
 * @property value necessary annotation retention (RUNTIME, BINARY or SOURCE)
 */
@Target(AnnotationTarget.ANNOTATION_CLASS)
public annotation class Retention(val value: AnnotationRetention = AnnotationRetention.RUNTIME)

/**
 * This meta-annotation determines that an annotation is applicable twice or more on a single code element
 */
@Target(AnnotationTarget.ANNOTATION_CLASS)
public annotation class Repeatable

/**
 * This meta-annotation determines that an annotation is a part of public API and therefore should be included in the generated
 * documentation for the element to which the annotation is applied.
 */
@Target(AnnotationTarget.ANNOTATION_CLASS)
public annotation class MustBeDocumented

   ④定义Annotation的方法不同

     java中使用 @interface ,kotlin 中使用 annotation class。

  ⑤枚举中的部分字段就不同。比如Java中RetentionPolity.CLASS对应 Kotlin中AnnotationRetention.BINARY,ElementType.ANNOTATION_TYPE 对应 AnnotationTarget.ANNOTATION_CLASS 但功能类似,改成了更为可读名称

@Retention(AnnotationRetention.SOURCE)
annotation class PageName{
    //语法形式上模拟了静态类的调用方法
    companion object{
        const val MAIN = "main"
        const val HOME = "home"
        const val ACGN = "acgn"
        const val SMALL_VIDEO = "small_video"
        const val GOLD = "gold"
        const val MINE = "mine"
        const val ABOUT = "about"
        const val DISCOVERY = "discovery"
    }
}

 

4、Androidx中的一些注解(androidx.annotation  |  Android Developers (google.cn)

  • 为什么enum影响性能?

        因为没有enum的值都会创建了一个Object对象,占用内存。

 

5、为什么@PageName能够限定方法的返回值是PageName内枚举值

      这里@PageName和@StringDef结合,实际上达到的是枚举的作用效果,可以方法参数前面,或者方法上方,指定参数的传值区间和返回值区间。这里是用作枚举。

 

6、有关PermissionX使用注解对是否请求权限的检查

 

【注解的作用】

1、编译检查

@PageName实际上也是起到这样的效果、@Override

2、生成对应的帮助文档

 

posted @ 2022-07-28 19:08  茄子鱼  阅读(349)  评论(0编辑  收藏  举报