【发布时间】:2017-08-24 16:37:19
【问题描述】:
根据 JLS (§8.4.3),方法修饰符的首选顺序是
Annotation public protected private abstract static final synchronized native strictfp
前提是注解(如果有的话)适用于方法(@Target(METHOD))。另一方面 (§9.7.4),任何非void 方法的返回类型的类型注释都应该紧跟在类型之前。
所以如果我们有一个方法注解:
@Target(METHOD)
@interface MethodAnnotation {
}
和一个类型注释:
@Target(TYPE_USE)
@interface TypeAnnotation {
}
那么示例方法的正确(根据首选编码风格)修饰符顺序将是
@MethodAnnotation
public static @TypeAnnotation T foo() {
// ...
}
现在考虑我们有一个适用于方法和类型的“混合”注释:
package com.example;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.TYPE_USE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
@Retention(RUNTIME)
@Target({METHOD, TYPE_USE})
@interface MethodOrTypeAnnotation {
// empty
}
当用于方法时,这样的注解将应用于方法及其返回类型。那么首选的代码风格是什么?
public static @MethodOrTypeAnnotation T foo() {
// ...
}
或者也许下面的版本更好?
@MethodOrTypeAnnotation
public static T foo() {
// ...
}
【问题讨论】:
-
投票结束为“主要基于意见”。我的观点是,同时带有
METHOD和TYPE_USE的注释会非常混乱,因为它同时应用两次,所以我说你应该避免这样的注释。像许多其他事情一样,仅仅因为语言允许,并不意味着您应该使用它。 -
@Andreas 好的,但大多数
@Nullable和@NonNull注释都有@Target({ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER, ElementType.LOCAL_VARIABLE, ElementType.TYPE_USE})。 -
好吧,不是全部而是一些,例如,参见
org.jetbrains.annotations.NotNull(org.jetbrains:annotations:jar:15.0)。 -
您指的是 JetBrains
@NotNull,而不是@NonNull?如果是这样,当在方法上给出时,它实际上适用于方法的返回值(空值被禁止返回(用于方法)),所以我想说你应该注释返回类型,而不是方法。如果注释方法意味着它适用于所有参数,就像@NonNullByDefault那样,那么您应该注释方法,而不是返回值。从本质上讲,将其放在对您的代码读者有意义的地方,这样意图就很清楚了。
标签: java java-8 annotations jls type-annotation