在https://dagger.dev/multibindings.html中,我读到了@AutoAnnotation。它引用了https://github.com/google/auto/blob/master/value/src/main/java/com/google/auto/value/AutoAnnotation.java。
我读到它,无法理解。
我设法使用我的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
但是我不知道如何使用。有使用它的任何好的教程吗?
[AutoAnnotation自动生成一个类,该类以与JDK相同的方式实现注释接口。
[通过使用自定义注释作为其键的Dagger使用Multibindings映射时,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
,则也可以使用unwrapKeys
使字符串以String而不是YourAnnotation作为键,但是假设您想要这样做,是因为您希望YourAnnotation将来具有多个值。但是YourAnnotation的实现是从哪里来的,应该如何在地图上调用get
?
当注释Java元素(通常是类,方法或字段)时,Java将返回该类的注释的特定实现。从Java tutorial:
@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本身是annotated with @Retention(RUNTIME)
),则可以通过@Retention(RUNTIME)
或Generation3List.class.getAnnotations()
进行访问。 (也有declared对等物以不同方式处理超类注释。)
一旦到达ClassPreamble的实例,就可以使用Generation3List.class.getAnnotations()
和Generation3List.class.getAnnotation(ClassPreamble.class)
之类的方法从类中检索数据。但是,ClassPreamble充当接口,并且该注释的实现在VM内部。这使得在运行时创建您自己的ClassPreamble任意实例变得更加困难。
因为YourAnnotation和ClassPreamble是接口,所以您可以只创建一个实现。但是,与VM的实现相比,该实现不太可能具有匹配的Generation3List.class.getAnnotation(ClassPreamble.class)
和author()
实现,因为在JRE之间实现可能有所不同,在Android中也可能有所不同。但是,实际上非常严格地规定了date()
和equals
的实现:
注释的哈希码是其成员(包括具有默认值的哈希值)的哈希码的总和,如下所示:注释成员的哈希码为(成员名称的哈希码的127倍为[...]
由String.hashCode())计算得出成员值的哈希码。如果指定的对象表示在逻辑上等效于该注释的注释,则返回true。换句话说,如果指定对象是与此实例具有相同注释类型的实例,并且其所有成员都与此注释的对应成员相同,则返回true,如下所示[...
可以手动实施这些规则,但是这样做很难,并且如果要更改YourAnnotation或ClassPreamble的结构,也将带来负担。通过
hashCode
,自动注释会自动为符合条件的实现生成代码:
equals
[使用AutoAnnotation的生成实现,您可以在Dagger Multibindings生成的地图上调用
hashCode
(或提供您控制的测试实现),而不必处理特定于批注的in the docs for Annotation XOR或there are reflective solutions to this problem规则。这在Dagger和测试之外非常有用,但是由于Dagger在其映射中使用了注释实例,因此您可能需要使用AutoAnnotation来创建类似实例是有意义的。