@AutoAnnotation的作用是什么?如何使用? [英] What is @AutoAnnotation for? How could it be used?

查看:96
本文介绍了@AutoAnnotation的作用是什么?如何使用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

https://dagger.dev/multibindings.html 中,我了解了@AutoAnnotation.它引用了

In https://dagger.dev/multibindings.html, I read about @AutoAnnotation. It has a reference to 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

It is also mentioned in https://github.com/google/auto/blob/57dfad360306619a820e6aae4a14a1aa67c29299/value/userguide/howto.md#annotation

我读到了它,无法理解它.

I read about it, can't get to understand it.

我设法使用我的Android代码访问它

I manage to access it from my Android code using

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

但是我不知道如何使用它.有使用它的任何好的教程吗?

But I don't understand how it could be used. Is there any good tutorial of using it?

推荐答案

AutoAnnotation automatically generates a class that implements an annotation interface in the same way the JDK does.

通过通过Dagger使用自定义注释作为其键的Multibindings映射时,Dagger会使用注释实例本身作为键,将实例T或提供程序Provider<T>安装到返回的映射中.为了使这一点更清楚:

When using a Multibindings map through Dagger that uses a custom annotation as its key, Dagger will install the instance T or Provider Provider<T> into the returned map, using the annotation instance itself as the key. To make this clearer:

@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?

If the only thing that matters here is foo, you could also use unwrapKeys to make the map keyed by String instead of YourAnnotation, but let's assume you want this because you want YourAnnotation to have multiple values in the future. But where do the implementations of YourAnnotation come from, and how are you supposed to call get on the map?

注释Java元素(通常是类,方法或字段)时,Java将返回该类的注释的特定实现.从 Java教程:

When you annotate a Java element (frequently a class, method, or field) Java will return a particular implementation of that class's annotation. From the 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本身是

In this usage, Generation3List has one Annotation of type ClassPreamble. If the annotation is retained at runtime (i.e. ClassPreamble itself is annotated with @Retention(RUNTIME)), you can get to it via Generation3List.class.getAnnotations() or Generation3List.class.getAnnotation(ClassPreamble.class). (There are also declared counterparts that handle superclass annotations differently.)

一旦到达ClassPreamble的实例,就可以使用author()date()之类的方法从类中检索数据.但是,ClassPreamble充当接口,并且该注释的实现在VM内部.这使得在运行时创建您自己的ClassPreamble任意实例变得更加困难.

Once you get to an instance of ClassPreamble, you can use the methods like author() and date() to retrieve the data out of the class. However, ClassPreamble behaves as an interface, and the implementation of that annotation is internal to the VM. That makes it more difficult to create your own arbitrary instance of ClassPreamble at runtime.

因为YourAnnotation和ClassPreamble是接口,所以您只需创建一个实现即可.但是,与VM的实现相比,该实现不太可能具有匹配的equalshashCode实现,因为JRE之间的实现可能有所不同,而在Android中也可能有所不同.但是,实际上非常严格地规定了equalshashCode的实现 :

Because YourAnnotation and ClassPreamble are interfaces, you could just create an implementation. However, that implementation is unlikely to have matching implementations of equals and hashCode compared to the VM's implementation, because the implementation may vary between JREs and may also vary in Android. However, the implementation of equals and hashCode is actually very closely prescribed in the docs for Annotation:

注释的哈希码是其成员(包括具有默认值的成员)的哈希码的总和,如下所示:注释成员的哈希码为(成员名称的哈希码的127倍)由String.hashCode())计算得出,对成员值的哈希码进行XOR,如下[...]

The hash code of an annotation is the sum of the hash codes of its members (including those with default values), as defined below: The hash code of an annotation member is (127 times the hash code of the member-name as computed by String.hashCode()) XOR the hash code of the member-value, as defined below [...]

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

Returns true if the specified object represents an annotation that is logically equivalent to this one. In other words, returns true if the specified object is an instance of the same annotation type as this instance, all of whose members are equal to the corresponding member of this annotation, as defined below [...]

可以手动实施这些规则,但是这样做很难,而且如果YourAnnotation或ClassPreamble的结构发生变化,也将带来负担.尽管仍然具有反思性解决方案,AutoAnnotation会自动为符合条件的实现生成代码:

It is possible to manually implement these rules, but it would be difficult to do so, and it would also impose a burden if the structure of YourAnnotation or ClassPreamble were to change. Though there are reflective solutions to this problem, AutoAnnotation generates the code for a conforming implementation automatically:

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的生成的实现,您可以在Dagger Multibindings生成的地图上调用get(或提供您控制的测试实现),而不必处理特定于批注的hashCode XOR或equals规则.这在Dagger和测试之外非常有用,但是由于Dagger在其映射中使用了注释实例,因此您可能需要使用AutoAnnotation来创建类似实例是有道理的.

With AutoAnnotation's generated implementation, you can call get on the map that Dagger Multibindings generates (or provide test implementations you control) without having to deal with Annotation-specific hashCode XORs or equals rules. This is useful beyond Dagger and tests, but because Dagger uses annotation instances in its maps, it makes sense that you might need to use AutoAnnotation to create similar instances.

这篇关于@AutoAnnotation的作用是什么?如何使用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆