1 回答

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 来创建类似的实例是有意义的。
添加回答
举报