Checkstyle Javaルール

CheckstyleのJavaルールについて1つずつまとめます

AnnotationLocation

CheckStyle公式ドキュメント

検証環境

Checkstyleバージョン:10.3.3
Javaバージョン:17


チェック概要

チェック追加バージョン
Checkstyle 6.0

アノテーションの位置をチェックする。デフォルトでは以下の項目をチェックする。

※ローカル変数のようなJavaDocコメントを持つことができない要素は、トークンタイプの指定で対象としている場合でも、チェックの対象範囲には含まれないので注意する。

※以下のようにアノテーションがアクセス修飾子と戻り値の型の間に配置されている場合もチェックの対象外となる。

public @Nullable Long getStartTimeOrNull() {
}

プロパティ

プロパティ デフォルト値 説明 追加
バージョン
allowSameline MultipleAnnotations boolean false 複数のアノテーションを対象要素と同じ行に配置することを許容するかどうか 6.0
allowSamelineSingle ParameterlessAnnotation boolean true 1つの属性なしアノテーションを対象要素と同じ行に配置することを許容するかどうか 6.1
allowSameline ParameterizedAnnotation boolean false 属性ありのアノテーションを1つだけ対象要素と同じ行に配置することを許容するかどうか 6.4
tokens トークンの サブセット CLASS_DEF,
INTERFACE_DEF,
PACKAGE_DEF,
ENUM_CONSTANT_DEF,
ENUM_DEF,
METHOD_DEF,
CTOR_DEF,
VARIABLE_DEF,
RECORD_DEF,
COMPACT_CTOR_DEF
チェック対象のトーク 6.0

トークンのサブセットには以下の値が設定可能

説明
ANNOTATION_DEF アノテーション宣言
ANNOTATION_FIELD_DEF アノテーションフィールドの宣言
CLASS_DEF クラス宣言
COMPACT_CTOR_DEF 引数なしコンストラクタ宣言
CTOR_DEF コンストラクター宣言
ENUM_CONSTANT_DEF Enum定数宣言
ENUM_DEF enum宣言
INTERFACE_DEF インターフェイス宣言
METHOD_DEF メソッド宣言
PACKAGE_DEF パッケージ宣言
RECORD_DEF レコード宣言
VARIABLE_DEF フィールドまたはローカル変数の宣言

設定+チェック実行結果

プロパティ設定なし

設定ファイル記述方法

<module name="Checker">
    <module name="TreeWalker">
        <module name="AnnotationLocation"/>
    </module>
</module>

チェック実行例

public class MyClass {
    // OK 属性なしアノテーション1つまでなら同行に記載可能
    @NotNull private boolean field1;

    // OK
    @NotNull
    private boolean field2;

    // NG 属性ありアノテーションは同行に記述しない
    @SuppressWarnings("deprecation") DataLoader loader;

    // NG 属性なしアノテーションは同行に1つのみ記述できる
    @NotNull @Mock DataLoader loader;

    // OK 属性なしアノテーション1つまでなら同行に記載可能
    @Override public int hashCode() {
        return 1;
    }

    // OK
    @Override
    public boolean equals(Object obj) {
        return true;
    }

    // NG 属性ありアノテーションは同行に記述しない
    @SuppressWarnings("deprecation") public int foo() {
        return 1;
    }
}

プロパティ設定あり

allowSamelineMultipleAnnotations

trueの場合、複数のアノテーションを対象要素と同じ行に配置することができる。(デフォルト:false)

設定ファイル記述方法

<module name="Checker">
    <module name="TreeWalker">
        <module name = "AnnotationLocation">
            <property name = "allowSamelineMultipleAnnotations" value = "true" />
        </module>
    </module>
</module>

チェック実行例

アノテーションを同行に複数記述しても構わないので、以下の記述は全てチェックOKとなる。

public class MyClass {
    // OK 
    @NotNull private boolean field1;

    // OK
    @NotNull
    private boolean field2;

    // OK 
    @SuppressWarnings("deprecation") DataLoader loader;

    // OK 
    @NotNull @Mock DataLoader loader;
    
    // OK 
    @Override public int hashCode() {
        return 1;
    }

    // OK
    @Override
    public boolean equals(Object obj) {
        return true;
    }

    // OK 
    @SuppressWarnings("deprecation") public int foo() {
        return 1;
    }
}

allowSamelineSingleParameterlessAnnotation

trueの場合、1つの属性なしアノテーションを対象要素と同じ行に配置できる。(デフォルト:true)

設定ファイル記述方法

<module name="Checker">
    <module name="TreeWalker">
        <module name = "AnnotationLocation">
            <property name = "allowSamelineSingleParameterlessAnnotation" value = "false" />
        </module>
    </module>
</module>

チェック実行例

アノテーションアノテーションの対象要素が同行に記載する場合チェックNGとなる。

public class MyClass {
    // NG アノテーションは同行に記述しない
    @NotNull private boolean field1;

    // OK
    @NotNull
    private boolean field2;

    // NG アノテーションは同行に記述しない
    @SuppressWarnings("deprecation") DataLoader loader;

    // NG アノテーションは同行に記述しない
    @NotNull @Mock DataLoader loader;
    
    // NG アノテーションは同行に記述しない
    @Override public int hashCode() {
        return 1;
    }

    // OK
    @Override
    public boolean equals(Object obj) {
        return true;
    }

    // NG アノテーションは同行に記述しない
    @SuppressWarnings("deprecation") public int foo() {
        return 1;
    }
}

allowSamelineParameterizedAnnotation

trueの場合、属性ありのアノテーションを1つだけ対象要素と同じ行に記載できる。(デフォルト:false)

設定ファイル記述方法

<module name="Checker">
    <module name="TreeWalker">
        <module name = "AnnotationLocation">
            <property name = "allowSamelineParameterizedAnnotation" value = "true" />
        </module>
    </module>
</module>

チェック実行例

属性の有無に関わらず、アノテーションは対象要素と同行に1つまでなら記載可能となる。

public class MyClass {
    // OK 属性なしアノテーション1つまでなら同行に記載可能
    @NotNull private boolean field1;

    // OK
    @NotNull
    private boolean field2;

    // OK 属性ありアノテーション1つまでなら同行に記載可能
    @SuppressWarnings("deprecation") DataLoader loader;

    // NG 属性なしアノテーションは同行に1つのみ記述できる
    @NotNull @Mock DataLoader loader;
    
    // OK 属性なしアノテーション1つまでなら同行に記載可能
    @Override public int hashCode() {
        return 1;
    }

    // OK
    @Override
    public boolean equals(Object obj) {
        return true;
    }

    // OK 属性ありアノテーション1つまでなら同行に記載可能
    @SuppressWarnings("deprecation") public int foo() {
        return 1;
    }
}

tokens

チェック対象のトークンをコンマ区切りで記述する。
※ローカル変数のようなJavaDocコメントを持つことができない要素は、トークンタイプの指定で対象としている場合でも、チェックの対象範囲には含まれないので注意する

設定ファイル記述方法

<module name="Checker">
    <module name="TreeWalker">
        <module name = "AnnotationLocation">
            <property name = "tokens" value = "METHOD_DEF" />
        </module>
    </module>
</module>

チェック実行例

public class MyClass {
    // OK メソッド宣言のみチェック対象なのでチェック対象外
    @NotNull private boolean field1;

    // OK メソッド宣言のみチェック対象なのでチェック対象外
    @NotNull
    private boolean field2;

    // OK メソッド宣言のみチェック対象なのでチェック対象外
    @SuppressWarnings("deprecation") DataLoader loader;

    // OK メソッド宣言のみチェック対象なのでチェック対象外
    @NotNull @Mock DataLoader loader;
    
    // OK 属性なしアノテーション1つまでなら同行に記載可能
    @Override public int hashCode() {
        return 1;
    }

    // OK
    @Override
    public boolean equals(Object obj) {
        return true;
    }

    // NG 属性ありアノテーションは同行に記述しない
    @SuppressWarnings("deprecation") public int foo() {
        return 1;
    }
}

トークンによって、プロパティの設定を切り替えたい場合は、以下のように設定を2つ記述することで対応可能となる。

<module name="Checker">
    <module name="TreeWalker">
        <module name = "AnnotationLocation">
            <property name="id" value="AnnotationLocationForMethodDef"/>
            <property name = "tokens" value = "METHOD_DEF" />
            <property name = "allowSamelineSingleParameterlessAnnotation" value = "false" />
        </module>
        <module name = "AnnotationLocation">
            <property name="id" value="AnnotationLocationForClassDef"/>
            <property name = "tokens" value = "CLASS_DEF" />
        </module>
    </module>
</module>