[英]What is the difference between field: array of annotation vs separate annotations
Is there a difference while expressing a set of annotations in two different ways?以两种不同的方式表达一组注释有区别吗? Will the result be the same?
结果会一样吗? Example:
例子:
class Sample {
@Inject
@CustomInfo
lateinit var fieldA: Any
@field:[
Inject
CustomInfo
]
lateinit var fieldB: Any
}
Annotations:注释:
@Qualifier
@Retention(AnnotationRetention.RUNTIME)
annotation class CustomInfo
and:和:
@Target({ METHOD, CONSTRUCTOR, FIELD })
@Retention(RUNTIME)
@Documented
public @interface Inject {}
Will there be the same output?会不会有同样的output?
The decompiled Java code produced:反编译的Java代码产生:
public final class Sample {
@Inject
public Object fieldA;
@Inject
@CustomInfo
public Object fieldB;
/** @deprecated */
// $FF: synthetic method
@CustomInfo
public static void getFieldA$annotations() {
}
}
Both ways of writing the annotations apply @Inject
and @CustomInfo
onto the line lateinit var fieldA: Any
.编写注释的两种方式都将
@Inject
和@CustomInfo
应用于lateinit var fieldA: Any
行。
However, there are multiple Java elements that are generated by this single Kotlin declaration - a backing field, a getter and setter - as well as the Kotlin property itself.但是,有多个 Java 元素是由单个 Kotlin 声明生成的 - 一个支持字段、一个 getter 和 setter - 以及 Kotlin 属性本身。 The second way:
第二种方式:
@field:[
Inject
CustomInfo
]
lateinit var fieldB: Any
explicitly states that you are applying these annotations to the underlying backing field.明确声明您正在将这些注释应用于底层支持字段。
The first way does not do that:第一种方法不会这样做:
@Inject
@CustomInfo
lateinit var fieldA: Any
Instead, Kotlin uses its own documented rules (explained below) to decide which thing to apply your annotations on.取而代之的是,Kotlin 使用其自己的文档化规则(如下所述)来决定应用注释的对象。
For each annotation, Kotlin finds all the targets available in the current context that the annotation can be applied on.对于每个注释,Kotlin 会查找当前上下文中可以应用注释的所有可用目标。
Now looking at your two annotations, Inject
is a Java annotation that can only be applied to fields, so for Inject
, it doesn't which way you write it.现在查看您的两个注释,
Inject
是一个 Java 注释,只能应用于字段,因此对于Inject
,它不是您编写的方式。
On the other hand, CustomInfo
lacks a Target
annotation, and so can be applied to both a property and a field (among other things).另一方面,
CustomInfo
缺少Target
注释,因此可以应用于属性和字段(除其他外)。 Kotlin would choose to apply it to the property if you do it this way:如果您这样做,Kotlin 会选择将其应用于属性:
@Inject
@CustomInfo
lateinit var fieldA: Any
Java code would not be able to find this annotation on the field, Looking at the decompiled code, it appears that the Kotlin compiler generates an additional, deprecated, synthetic method with @CustomInfo
on it. Java 代码将无法在该字段上找到此注释,查看反编译代码,似乎 Kotlin 编译器生成了一个附加的、已弃用的、带有
@CustomInfo
的合成方法。
Side note: the []
doesn't actually create an "array".旁注:
[]
实际上并没有创建“数组”。 It's just some delimiters so that the parser (and the person reading the code) knows more easily which annotations are associated with @field:
and which are not.它只是一些分隔符,以便解析器(以及阅读代码的人)更容易知道哪些注释与
@field:
相关联,哪些不相关。
See also: Annotation Use-site Targets另请参阅: 注释使用站点目标
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.