【问题标题】:Preferred modifier order for annotated methods [closed]注释方法的首选修饰符顺序[关闭]
【发布时间】: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() {
        // ...
}

【问题讨论】:

  • 投票结束为“主要基于意见”。我的观点是,同时带有METHODTYPE_USE 的注释会非常混乱,因为它同时应用两次,所以我说你应该避免这样的注释。像许多其他事情一样,仅仅因为语言允许,并不意味着您应该使用它。
  • @Andreas 好的,但大多数 @Nullable@NonNull 注释都有 @Target({ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER, ElementType.LOCAL_VARIABLE, ElementType.TYPE_USE})
  • 真的吗? Eclipse NonNull 仅是 TYPE_USEAndroid 也一样。在Lombok 中是METHOD,但不是TYPE_USE。那么你指的是什么“最”?
  • 好吧,不是全部而是一些,例如,参见org.jetbrains.annotations.NotNull (org.jetbrains:annotations:jar:15.0)。
  • 您指的是 JetBrains @NotNull,而不是 @NonNull?如果是这样,当在方法上给出时,它实际上适用于方法返回值(空值被禁止返回(用于方法),所以我想说你应该注释返回类型,而不是方法。如果注释方法意味着它适用于所有参数,就像@NonNullByDefault 那样,那么您应该注释方法,而不是返回值。从本质上讲,将其放在对您的代码读者有意义的地方,这样意图就很清楚了。

标签: java java-8 annotations jls type-annotation


【解决方案1】:

声明一个注解既是类型注解又是声明注解是bad style。您应该避免创建此类注释。

cmets 给出了一些 @Nullable@NonNull 注释作为示例,它们旨在与处理类型注释的现代工具和在 Java 具有类型注释之前编写的旧工具一起使用。这种类型和声明注释是一种临时措施,打算在该工具支持 Java 8 之前使用,并且不再需要。 link above 提供了其他示例以及如何避免它们。

也就是说,如果您确实有 Frankenstein 类型和声明注释,最好将其写在代表其主要含义的位置或在此上下文中使用的位置。 在实践中,属性通常是类型属性,因此注释应该与其他类型注释一起写在类型前面。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-19
    • 2021-01-20
    • 2018-09-02
    • 1970-01-01
    相关资源
    最近更新 更多