首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >“自动注释”是指什么?怎么能用呢?

“自动注释”是指什么?怎么能用呢?
EN

Stack Overflow用户
提问于 2019-10-07 01:55:12
回答 1查看 561关注 0票数 0

https://dagger.dev/multibindings.html中,我读到了关于@AutoAnnotation的文章。它引用了https://github.com/google/auto/blob/master/value/src/main/java/com/google/auto/value/AutoAnnotation.java

https://github.com/google/auto/blob/57dfad360306619a820e6aae4a14a1aa67c29299/value/userguide/howto.md#annotation中也提到了

我读过它,无法理解它。

我设法从我的Android代码访问它

代码语言:javascript
复制
implementation 'com.google.auto.value:auto-value:1.5.2'
kapt 'com.google.auto.value:auto-value:1.5.2'

而且还

代码语言:javascript
复制
android.defaultConfig.javaCompileOptions.annotationProcessorOptions.includeCompileClasspath = true

但我不明白它怎么会被使用。有使用它的好教程吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-10-07 19:26:23

AutoAnnotation自动生成一个类,该类实现注释接口的方式与JDK相同。

匕首地图键

当使用使用自定义注释作为键的Dagger的多绑定映射时,Dagger将将实例T或Provider Provider<T>安装到返回的映射中,使用注释实例本身作为键。为了使这一点更清楚:

代码语言:javascript
复制
@MapKey
@interface YourAnnotation {
  String foo();
}

@Provides @YourAnnotation(foo="bar") YourClass getYourClassForBar() { /* ... */ }

// Dagger will create a multibinding that would allow you to inject this:
@Inject Map<YourAnnotation, YourClass> map;

如果这里唯一重要的是foo,您也可以使用unwrapKeys来使映射由字符串而不是YourAnnotation键键,但是让我们假设您希望这样做,因为您希望YourAnnotation将来具有多个值。但是YourAnnotation的实现是从哪里来的,您应该如何在地图上调用get呢?

运行时注解

当您注释Java元素(通常是类、方法或字段)时,Java将返回该类注释的特定实现。来自Java教程

代码语言:javascript
复制
@interface ClassPreamble {
   String author();
   String date();
   int currentRevision() default 1;
   String lastModified() default "N/A";
   String lastModifiedBy() default "N/A";
   // Note use of array
   String[] reviewers();
}

// [...]

@ClassPreamble (
   author = "John Doe",
   date = "3/17/2002",
   currentRevision = 6,
   lastModified = "4/12/2004",
   lastModifiedBy = "Jane Doe",
   // Note array notation
   reviewers = {"Alice", "Bob", "Cindy"}
)
public class Generation3List extends Generation2List {/* ... */}

在这种用法中,Generation3List有一个ClassPreamble类型的注释。如果在运行时保留注释(即ClassPreamble本身是@Retention(RUNTIME)),则可以通过Generation3List.class.getAnnotations()Generation3List.class.getAnnotation(ClassPreamble.class)访问它。(也有声明的对应方以不同的方式处理超类注释。)

一旦到达ClassPreamble实例,就可以使用author()date()等方法从类中检索数据。但是,ClassPreamble作为一个接口运行,该注释的实现是VM的内部实现。这使得在运行时创建您自己的任意ClassPreamble实例变得更加困难。

一致性注释实现

因为YourAnnotation和ClassPreamble是接口,所以您可以创建一个实现。然而,与VM的实现相比,该实现不太可能有与equalshashCode相匹配的实现,因为JRE的实现可能有所不同,而且在Android中也可能有所不同。然而,equalshashCode的实现实际上是非常严格的在文档中作注释

注释的哈希代码是其成员的哈希代码(包括默认值)的总和,如下所定义:注释成员的哈希代码是(由String.hashCode()计算的成员名称哈希代码的127倍) XOR成员值的哈希代码,如下所定义的. 如果指定的对象表示与此注释在逻辑上等效的注释,则返回true。换句话说,如果指定的对象是与此实例相同的注释类型的实例,则返回true,该实例的所有成员都等于该注释的对应成员,如下所定义.

手动实现这些规则是可能的,但是很难这样做,如果改变YourAnnotation或ClassPreamble的结构,也会带来负担。虽然是对于这个问题,有反思性的解决办法,但AutoAnnotation会自动为符合标准的实现生成代码:

代码语言:javascript
复制
public class YourAnnotations {
  @AutoAnnotation public static YourAnnotation yourAnnotation(String foo) {
    return new AutoAnnotation_YourAnnotations_yourAnnotation(foo);
  }
}

public class ClassPreambles {
  @AutoAnnotation public static ClassPreamble classPreamble(
      String author,
      String date,
      int currentRevision,
      String lastModified,
      String lastModifiedBy,
      String[] reviewers) {
    return new AutoAnnotation_ClassPreambles_classPreamble(
        author,
        date,
        currentRevision,
        lastModified,
        lastModifiedBy,
        reviewers);
  }
}

使用自动注释的生成实现,您可以在DaggerMultibinding生成(或提供您控制的测试实现)地图上调用get,而不必处理特定于注释的hashCode XOR或equals规则。这在Dagger和测试之外是有用的,但是因为Dagger在其映射中使用注释实例,所以您可能需要使用AutoAnnotation来创建类似的实例。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58262660

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档