为了账号安全,请及时绑定邮箱和手机立即绑定

@AutoAnnotation 有什么用?怎么可以用呢?

@AutoAnnotation 有什么用?怎么可以用呢?

长风秋雁 2023-09-27 16:19:41
在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 代码访问它implementation 'com.google.auto.value:auto-value:1.5.2' kapt 'com.google.auto.value:auto-value:1.5.2'并且android.defaultConfig.javaCompileOptions.annotationProcessorOptions.includeCompileClasspath = true但我不明白它可以如何使用。有没有什么好的使用教程?
查看完整描述

1 回答

?
慕妹3146593

TA贡献1820条经验 获得超9个赞

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

匕首地图键

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


@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,您还可以使用unwrapKeysString 而不是 YourAnnotation 来制作地图键控,但我们假设您需要这样做,因为您希望 YourAnnotation 将来具有多个值。但是 YourAnnotation 的实现从哪里来,以及如何get在地图上调用?


运行时注释

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


@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 的实现相匹配的实现,并且与 VM 的实现相比,因为 JRE 之间的实现可能有所不同,而且 Android 中的实现也可能有所不同equals。然而, Annotation 的文档中实际上非常详细地规定了和hashCode的实现:equalshashCode


注解的哈希码是其成员(包括具有默认值的成员)的哈希码之和,定义如下: 注解成员的哈希码是(成员名称哈希码的 127 倍,计算公式为: String.hashCode()) 对成员值的哈希码进行异或,定义如下 [...]


如果指定对象表示逻辑上与此等效的注释,则返回 true。换句话说,如果指定对象是与此实例具有相同注释类型的实例,并且其所有成员都等于此注释的相应成员,则返回 true,如下定义 [...]


手动实现这些规则是可以的,但是这样做会很困难,而且如果YourAnnotation或ClassPreamble的结构发生改变也会带来负担。尽管这个问题有反射性的解决方案,但 AutoAnnotation 会自动生成符合要求的实现的代码:


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);

  }

}

通过 AutoAnnotation 生成的实现,您可以调用getDagger Multibindings 生成的地图(或提供您控制的测试实现),而无需处理特定于注释的hashCodeXOR 或equals规则。这在 Dagger 和测试之外很有用,但由于 Dagger 在其地图中使用注释实例,因此您可能需要使用 AutoAnnotation 来创建类似的实例是有意义的。


查看完整回答
反对 回复 2023-09-27
  • 1 回答
  • 0 关注
  • 43 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信