Kotlin中省略显式注解使用目标何时会存在风险?
近期Android Studio开始高亮Kotlin代码中的部分注解用法,并弹出如下警告:
The annotation is only applied to the parameter.
An explicit annotation use-site target is recommended.

添加显式注解使用目标可消除该警告,但疑惑是否需每次都添加,还是仅特定场景下有必要。既然这只是警告,请问何时必须添加显式注解使用目标?
先搞懂警告本质
Kotlin里很多注解可以作用在不同的「使用位点」——比如构造参数、类属性、成员字段、getter方法等。当你没写显式目标时,编译器会按注解的默认规则选一个位点,但这个默认选择可能和你实际想让注解生效的地方不符,IDE才会弹出这个警告。
这几种情况必须加显式目标
默认位点不符合你的实际需求
比如用Gson的@SerializedName时,如果你直接写在构造参数上,编译器默认只会把注解挂在参数上,但Gson需要注解作用于类的字段或属性才能正常序列化/反序列化。这时候必须显式写@field:SerializedName("user_name")或者@property:SerializedName("user_name"),否则序列化逻辑会失效。需要让注解同时作用在多个位点
如果你想让一个注解既作用于构造参数,又作用于对应的类属性,就必须分别指定目标,比如@get:Log @param:Log val age: Int。不写显式目标的话,注解只会作用在默认位点,达不到多位点生效的效果。注解本身没有明确默认位点
有些自定义注解或者第三方注解的定义里,没有指定默认的作用位点(或者默认规则模糊),这时候编译器无法自动推断,必须你显式指定目标,否则注解可能完全不生效,甚至后续出现编译错误。
这些场景可以不用加
如果你的注解默认作用位点完全符合需求,而且不存在歧义,就可以不用显式加。比如自定义的@CheckNotNull注解,它的设计目标就是校验构造参数,直接写在参数上时,编译器默认的位点就是参数,不会有问题,这时候可以忽略警告(或者在IDE里针对性关闭这个警告)。
内容的提问来源于stack exchange,提问作者Stanisław Olszak

