1 回答

TA貢獻1820條經(jīng)驗 獲得超9個贊
AutoAnnotation自動生成一個類,該類以與 JDK 相同的方式實現(xiàn)注釋接口。
匕首地圖鍵
當通過 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 的實現(xiàn)從哪里來,以及如何get在地圖上調(diào)用?
運行時注釋
當您注釋 Java 元素(通常是類、方法或字段)時,Java 將返回該類注釋的特定實現(xiàn)。來自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()從類中檢索數(shù)據(jù)。然而,ClassPreamble 表現(xiàn)為一個接口,并且該注釋的實現(xiàn)是在 VM 內(nèi)部的。這使得在運行時創(chuàng)建您自己的任意 ClassPreamble 實例變得更加困難。
符合注釋的實現(xiàn)
由于 YourAnnotation 和 ClassPreamble 是接口,因此您只需創(chuàng)建一個實現(xiàn)即可。但是,該實現(xiàn)不太可能具有與 VM 的實現(xiàn)相匹配的實現(xiàn),并且與 VM 的實現(xiàn)相比,因為 JRE 之間的實現(xiàn)可能有所不同,而且 Android 中的實現(xiàn)也可能有所不同equals。然而, Annotation 的文檔中實際上非常詳細地規(guī)定了和hashCode的實現(xiàn):equalshashCode
注解的哈希碼是其成員(包括具有默認值的成員)的哈希碼之和,定義如下: 注解成員的哈希碼是(成員名稱哈希碼的 127 倍,計算公式為: String.hashCode()) 對成員值的哈希碼進行異或,定義如下 [...]
如果指定對象表示邏輯上與此等效的注釋,則返回 true。換句話說,如果指定對象是與此實例具有相同注釋類型的實例,并且其所有成員都等于此注釋的相應成員,則返回 true,如下定義 [...]
手動實現(xiàn)這些規(guī)則是可以的,但是這樣做會很困難,而且如果YourAnnotation或ClassPreamble的結構發(fā)生改變也會帶來負擔。盡管這個問題有反射性的解決方案,但 AutoAnnotation 會自動生成符合要求的實現(xiàn)的代碼:
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 生成的實現(xiàn),您可以調(diào)用getDagger Multibindings 生成的地圖(或提供您控制的測試實現(xiàn)),而無需處理特定于注釋的hashCodeXOR 或equals規(guī)則。這在 Dagger 和測試之外很有用,但由于 Dagger 在其地圖中使用注釋實例,因此您可能需要使用 AutoAnnotation 來創(chuàng)建類似的實例是有意義的。
添加回答
舉報