慕妹3146593
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 来创建类似的实例是有意义的。