Skip to content

Latest commit

 

History

History
2620 lines (2101 loc) · 53.5 KB

CHECKSTYLE.md

File metadata and controls

2620 lines (2101 loc) · 53.5 KB

Checkstyle

Checkstyle에서 제공되는 모듈 내용을 정리한다.

Link

checkstyle 검사를 제외할 파일 패턴 설정.

<module name="BeforeExecutionExclusionFileFilter">
    <property name="fileNamePattern" value="module\-info\.java$"/>
</module>

annotation의 위치를 검사.

<module name="AnnotationLocation">
    <property name="id" value="AnnotationLocationMostCases"/>
    <property name="tokens"
            value="CLASS_DEF, INTERFACE_DEF, ENUM_DEF, METHOD_DEF, CTOR_DEF"/>
</module>
<module name="AnnotationLocation">
    <property name="id" value="AnnotationLocationVariables"/>
    <property name="tokens" value="VARIABLE_DEF"/>
    <property name="allowSamelineMultipleAnnotations" value="true"/>
</module>

VIOLATION

@Override @Nullable
public String foo() {
    return "bar";
}

@SuppressWarnings("deprecation") public String foo() {
    return "bar";
}

OK

@Override
@Nullable
public String foo() {
    return "bar";
}

@SuppressWarnings("deprecation")
public String foo() {
    return "bar";
}

// allow one single parameterless annotation on the same line
@Override public String foo() {
    return "bar";
}

@SuppressWarnings("deprecation") @Mock DataLoader loader;

@inheritDoc이 부여된 메소드가 override 됐는지를 검사.

<module name="MissingOverride"/>

VIOLATION

/*
 * {@inheritDoc}
 */
public void foo() {
}

OK

/*
 * {@inheritDoc}
 */
@Override
public void foo() {
}

nested block이 존재하는지 검사.

<module name="AvoidNestedBlocks"/>

VIOLATION

int foo = 0;
{
    foo = 3;
}

OK

int foo = 0;
foo = 3;

empty block이 존재하는지 검사.

<module name="EmptyBlock">
    <property name="option" value="TEXT"/>
    <property name="tokens"
              value="LITERAL_TRY, LITERAL_FINALLY, LITERAL_IF, LITERAL_ELSE, LITERAL_SWITCH"/>
</module>

VIOLATION

if (foo == bar) {
} else {
    System.out.println("not equal");
}

OK

if (foo != bar) {
    System.out.println("not equal");
}

비어있는 catch block을 검사.

<module name="EmptyCatchBlock">
    <property name="exceptionVariableName" value="expected"/>
</module>

VIOLATION

try {
    throw new RuntimeException();
} catch (RuntimeException e) {
}

OK

try {
    throw new RuntimeException();
} catch (RuntimeException expected) {
}

try {
    throw new RuntimeException();
} catch (RuntimeException e) {
    e.printStackTrace();
}

LeftCurly('{')의 줄바꿈을 검사.

<module name="LeftCurly">
    <property name="tokens"
              value="ANNOTATION_DEF, CLASS_DEF, CTOR_DEF, ENUM_CONSTANT_DEF, ENUM_DEF,
                     INTERFACE_DEF, LAMBDA, LITERAL_CASE, LITERAL_CATCH, LITERAL_DEFAULT,
                     LITERAL_DO, LITERAL_ELSE, LITERAL_FINALLY, LITERAL_FOR, LITERAL_IF,
                     LITERAL_SWITCH, LITERAL_SYNCHRONIZED, LITERAL_TRY, LITERAL_WHILE, METHOD_DEF,
                     OBJBLOCK, STATIC_INIT"/>
</module>

VIOLATION

if (foo == bar)
{
    System.out.println("equal");
}
else
{
    System.out.println("not equal");
}

OK

if (foo == bar) {
    System.out.println("equal");
} else {
    System.out.println("not equal");
}

brace('{', '}')가 존재하는지 검사.

<module name="NeedBraces">
    <property name="tokens"
              value="LITERAL_DO, LITERAL_ELSE, LITERAL_FOR, LITERAL_IF, LITERAL_WHILE"/>
</module>

VIOLATION

if (foo == bar)
    System.out.println("equal");
else
    System.out.println("not equal");

OK

if (foo == bar) {
    System.out.println("equal");
} else {
    System.out.println("not equal");
}

RightCurly('}')의 줄바꿈을 검사.

<module name="RightCurly">
    <property name="id" value="RightCurlySame"/>
    <property name="tokens"
              value="LITERAL_TRY, LITERAL_CATCH, LITERAL_FINALLY, LITERAL_IF, LITERAL_ELSE,
                     LITERAL_DO"/>
</module>

VIOLATION

if (foo == bar) {
    System.out.println("equal"); }
else {
    System.out.println("not equal"); }

OK

if (foo == bar) {
    System.out.println("equal");
} else {
    System.out.println("not equal");
}

private 생성자를 가진 클래스의 modifier가 final인지를 검사.

<module name="FinalClass"/>

VIOLATION

class Foo {
    private Foo() {
    }
}

OK

final class Foo {
    private Foo() {
    }
}

static 메소드만 가지는 util 클래스의 생성자가 private인지를 검사.

<module name="HideUtilityClassConstructor"/>

VIOLATION

class Util {
    public static void add(int a, int b) { }
    public static void div(int a, int b) { }
}

OK

class Util {
    private Util() {
    }
    public static void add(int a, int b) { }
    public static void div(int a, int b) { }
}

interface가 type으로 쓰이는지를 검사.

<module name="InterfaceIsType"/>

VIOLATION

interface Foo {
    int BAR = 100;
}

OK

class Foo {
    private Foo() {
    }
    public static final int BAR = 100;
}

하나의 파일에 두개 이상의 클래스를 정의했는지를 검사.

<module name="OneTopLevelClass"/>

VIOLATION

// Parent.java
class Parent {
}
class Child {
}

OK

// Parent.java
class Parent {
}

// Child.java
class Child {
}

클래스 멤버의 modifier가 private, protected 인지를 검사.

<module name="VisibilityModifier">
    <property name="protectedAllowed" value="true"/>
</module>

VIOLATION

int foo;
int bar;
public final int baz;
public int qux;

OK

private int foo;
protected int bar;
private final int int baz
protected int qux

switch에서 default 뒤에 case가 존재하는지 검사.

<module name="DefaultComesLast"/>

VIOLATION

switch (foo) {
    case 1:
        break;
    default:
    case 2:
        break;
}

OK

switch (foo) {
    case 1:
        break;
    case 2:
    default:
        break;
}
<module name="EmptyStatement"/>

VIOLATION

if (foo == bar);
    System.out.println("baz");  // always print baz

OK

if (foo == bar) {
    System.out.println("baz");
}

equals 메소드를 override하면 hashcode 메소드도 override 했는지 검사.

<module name="EqualsHashCode"/>

VIOLATION

class Foo {
    @Override
    public boolean equals(Object obj) {
        return ...
    }
}

OK

class Foo {
    @Override
    public boolean equals(Object obj) {
        return ...
    }

    @Override
    public int hashCode() {
        return ...
    }
}

switch-case에 fall through를 하는 곳에 "falls?[ -]?thr(u|ough)" 패턴의 주석이 존재하는지 검사.

<module name="FallThrough">
    <property name="reliefPattern" value="falls?[ -]?thr(u|ough)"/>
</module>

VIOLATION

int i = 0;
switch (i) {
    case 0:
        i++;
    case 1:
        i++;
    case 2:
    case 3: {
        i++;
    }
    default:
    break;
}

OK

int i = 0;
switch (i) {
    case 0:
        i++;
    // fall through
    case 1:
        i++;
    // fall through
    case 2:
    case 3: {
        i++;
    }
    // fall through
    default:
    break;
}

escape sequence를 8진수, 유니코드로 표현했는지를 검사.

<module name="IllegalTokenText">
    <property name="tokens" value="STRING_LITERAL, CHAR_LITERAL"/>
    <property name="format"
              value="\\u00(09|0(a|A)|0(c|C)|0(d|D)|22|27|5(C|c))|\\(0(10|11|12|14|15|42|47)| 134)"/>
    <property name="message"
              value="Consider using special escape sequence instead of octal value or Unicode  escaped value."/>
</module>

VIOLATION

char tab = '\u0009';
char octalTab = '\011';

OK

char escapedSequenceTab = '\t';

switch에서 default가 존재하는지 검사.

<module name="MissingSwitchDefault"/>

VIOLATION

switch (i) {
    case 1:
        break;
    case 2:
        break;
}

OK

switch (i) {
    case 1:
        break;
    case 2:
        break;
    default:
        break;
}

변수를 comma(',')를 사용하여 정의하였는지 검사.

<module name="MultipleVariableDeclarations"/>

VIOLATION

int foo, bar, fooarray[];

OK

int foo;
int bar;
int[] fooarray;

finalize 메소드를 override 했는지 검사.

<module name="NoFinalizer"/>

VIOLATION

class Foo {

    @Override
    protected void finalize() throws Throwable {
        super.finalize();
    }

}

OK

class Foo {
}

한 라인에 다수의 statement가 존재하는지 검사.

<module name="OneStatementPerLine"/>

VIOLATION

int var = 1, var2 = 2;
foo++; bar++;

OK

int var = 1
int var2 = 2;
var1++;
var2++;

오버로드 메소드의 순서를 검사.

<module name="OverloadMethodsDeclarationOrder"/>

VIOLATION

public void foo(int i) { }

public void foo(String s) { }

public void bar() { }

public void foo(int i, String s) { }

OK

public void foo(int i) { }

public void foo(String s) { }

public void foo(int i, String s) { }

public void bar() { }
<module name="SimplifyBooleanExpression"/>

VIOLATION

if (foo == false) { }

OK

if (!foo) { }
<module name="SimplifyBooleanReturn"/>

VIOLATION

if (foo()) {
    return true;
} else {
    return false;
}

OK

return foo();
<module name="StringLiteralEquality"/>

VIOLATION

if (foo == "bar") {
}

OK

if (foo.equals("bar")) {
}

부모의 clone() 호출을 검사.

<module name="SuperClone"/>

VIOLATION

@Override
public Object clone throws CloneNotSupportedException {
    return ...
}

OK

@Override
public Object clone throws CloneNotSUpportedException {
    super.clone();
    return ...
}

변수 정의와 변수 사용 사이의 거리가 3을 초과하지 않았는지를 검사.

<module name="VariableDeclarationUsageDistance">
    <property name="allowedDistance" value="3"/>
</module>

VIOLATION

int foo = 0;
int bar = 0;
int baz;
foo = foo + bar;  // foo distance is 3     : OK
bar = foo + foo;  // bar distance is 3     : OK
int qux;
baz = bar;        // baz distance is 4     : VIOLATION

OK

int foo = 0;
int bar = 0;
int baz;
foo = foo + bar;  // foo distance is 3     : OK
bar = foo + foo;  // bar distance is 3     : OK
baz = bar;        // baz distance is 3     : OK

star('*') import가 존재하는지 검사.

<module name="AvoidStarImport"/>

VIOLATION

import foo.bar.*;

OK

import foo.bar.Baz;

import 순서를 검사.

<module name="CustomImportOrder">
    <property name="sortImportsInGroupAlphabetically" value="true"/>
    <property name="separateLineBetweenGroups" value="true"/>
    <property name="customImportOrderRules" value="STATIC###THIRD_PARTY_PACKAGE"/>
    <property name="tokens" value="IMPORT, STATIC_IMPORT, PACKAGE_DEF"/>
</module>

VIOLATION

import java.util.Map;
import java.util.List;
import java.util.ArrayList;

OK

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

sun 패키지의 import가 존재하는지 검사.

<module name="IllegalImport"/>

VIOLATION

import sun.management.counter.StringCounter;

java.lang, 중복, 현재 패키지의 import를 검사.

<module name="RedundantImport"/>

VIOLATION

package foo;

import java.lang.String;   // java.lang
import java.lang.String;   // duplicate
import foo.Bar;            // same package

사용되지 않는 import를 검사.

<module name="UnusedImports"/>

VIOLATION

import java.util.ArrayList;

public class Foo {
    public static void main() {
        System.out.println("foo");
    }
}

OK

public class Foo {
    public static void main() {
        System.out.println("foo");
    }
}

tag 순서를 검사.

  1. @param
  2. @return
  3. @throws
  4. @deprecated
<module name="AtclauseOrder">
    <property name="tagOrder" value="@param, @return, @throws, @deprecated"/>
    <property name="target"
              value="CLASS_DEF, INTERFACE_DEF, ENUM_DEF, METHOD_DEF, CTOR_DEF, VARIABLE_DEF"/>
</module>

VIOLATION

/**
 * @return bar string
 * @param foo foo integer
 * @param bar bar integer
 */
public String foo(int foo, int bar) {
    return "bar";
}

OK

/**
 * @param foo foo integer
 * @param bar bar integer
 * @return bar string
 */
public String foo(int foo, int bar) {
    return "bar";
}

public 메소드에서 @param, @return tag 생략이 가능하도록 함.

<module name="JavadocMethod">
    <property name="scope" value="public"/>
    <property name="allowMissingParamTags" value="true"/>
    <property name="allowMissingReturnTag" value="true"/>
    <property name="allowedAnnotations" value="Override, Test"/>
    <property name="tokens" value="METHOD_DEF, CTOR_DEF, ANNOTATION_FIELD_DEF"/>
</module>

OK

// allow missing @param, @return tag */
/**
 * This is foo method.
 */
public String foo(int foo, int bar) {
    return "bar";
}

부적절한 javadoc의 위치를 검사.

<module name="InvalidJavadocPosition"/>

VIOLATION

@SuppressWarnings("foo")
/**
 * This comment looks like javadoc but it at an invalid location.
 * Therefore, the text will not get into Foo.html and the check will produce a violation.
 */
public class Foo {
}

OK

/**
 * This comment looks like javadoc but it at an invalid location.
 * Therefore, the text will not get into Foo.html and the check will produce a violation.
 */
@SuppressWarnings("foo")
public class Foo {
}

paragraph(<p>) 태그를 검사.

<module name="JavadocParagraph"/>

VIOLATION

/**
 * No tag
 *
 * <p>Tag immediately before the text.
 * <p>No blank line before the tag.
 *
 * <p>
 * New line after tag.
 *
 * <p> Whitespace after tag.
 */
public class TestClass {
}

OK

/**
 * No tag
 *
 * <p>Tag immediately before the text.
 *
 * <p>No blank line before the tag.
 *
 * <p>New line after tag.
 *
 * <p>Whitespace after tag.
 */

적절하지 않거나 존재하지 않는 HTML 태그 사용 및 첫 문장에 마침표를 사용했는지 검사.

<module name="JavadocStyle"/>

VIOLATION

/**
 * This is Foo class
 * <foo>This is Foo class</foo>
 */
class Foo {
}

OK

/**
 * This is Foo class.
 * <h1>This is Foo class</h1>
 */
class Foo {
}

indentation (4 spaces) 검사.

<module name="JavadocTagContinuationIndentation"/>

VIOLATION

/**
 * @param foo
 *   foo integer
 * @param bar
 *   bar integer
 * @return bar string
 */
public String foo(int foo, int bar) {
    return "bar";
}

OK

/**
 * @param foo
 *     foo integer
 * @param bar
 *     bar integer
 * @return bar string
 */

public type(annotation/enum/class/interface)에서 @param 생략이 가능하도록 함

<module name="JavadocType">
    <property name="scope" value="public"/>
    <property name="allowMissingParamTags" value="true"/>
</module>

OK

// allow missing @param tag */
/**
 * This is Foo class
 */
public class Foo<T> {
    ...
}

2라인을 넘어가는 메소드의 javadoc이 존재하는지 검사.

<module name="MissingJavadocMethod">
    <property name="scope" value="public"/>
    <property name="minLineCount" value="2"/>
    <property name="allowedAnnotations" value="Override, Test"/>
    <property name="tokens" value="METHOD_DEF, CTOR_DEF, ANNOTATION_FIELD_DEF"/>
</module>

VIOLATION

public String foo(int foo, int bar) { // minLineCount is > 2
    System.out.println("foo");
    System.out.println("bar");
    return "bar";
}

OK

/**
 * This is foo method.
 */
public String foo(int foo, int bar) {
    System.out.println("foo");
    System.out.println("bar");
    return "bar";
}

public String foo(int foo, int bar) { // minLineCount is <= 2
    System.out.println("foo");
    return "bar";
}

@Override
public String foo(int foo, int bar) { // @Override, @Test is allowed
    System.out.println("foo");
    System.out.println("bar");
    return "bar";
}

@param, @return, @throws, @deprecated의 설명이 존재하는지 검사.

<module name="NonEmptyAtclauseDescription"/>

VIOLATION

/**
 * @param foo
 * @param bar
 * @return bar string
 */
public String foo(int foo, int bar) {
    return "bar";
}

OK

/**
 * @param foo foo integer
 * @param bar bar integer
 * @return bar string
 */
public String foo(int foo, int bar) {
    return "bar";
}

단일 라인의 inline 태그가 존재하는지 검사.

<module name="SingleLineJavadoc">
    <property name="ignoreInlineTags" value="false"/>
</module>

VIOLATION

/** Single line Javadoc that references {@link String}. */
public void foo() { // not allowed inline tag. only allowed multi-line 
}

OK

/**
 * Single line Javadoc that references {@link String}.
 */
public void foo() {
}

/** Single line Javadoc. */
public void foo() {
}

summary 첫 문장이 마침표로 끝나는지 검사.

<module name="SummaryJavadoc">
    <property name="forbiddenSummaryFragments"
              value="^@return the *|^This method returns |^A [{]@code [a-zA-Z0-9]+[}]( is a )"/>
</module>

VIOLATION

/**
 * This is foo method
 */
public String foo(int foo, int bar) {
    return "bar";
}

/**
 *
 */
public String baz() {
    return "qux";
}

OK

/**
 * This is foo method.
 */
public String foo(int foo, int bar) {
    return "bar";
}

배열 타입 스타일을 검사.

<module name="ArrayTypeStyle"/>

VIOLATION

String foo[];

OK

String[] foo;

유니코드를 사용했는지 검사.

<module name="AvoidEscapedUnicodeCharacters">
    <property name="allowEscapesForControlCharacters" value="true"/>
    <property name="allowByTailComment" value="true"/>
    <property name="allowNonPrintableEscapes" value="true"/>
</module>

VIOLATION

String foo = "\u00B5"; // micro sign

OK

String foo = "μs";     // micro sign

// allowEscapesForControlCharacters
String bar = "\u200E";
// allow by allowByTailComment
String baz = "\u03BCS"; // the reader has no idea what this is.
// allow by allowNonPrintableEscapes */
String qux = "\u0020";

주석의 indentation을 검사.

<module name="CommentsIndentation">
    <property name="tokens" value="SINGLE_LINE_COMMENT, BLOCK_COMMENT_BEGIN"/>
</module>

VIOLATION

    /*
    foo is true
*/
boolean foo = true;

    // bar is true
boolean bar = true;

OK

/*
    foo is true
*/
boolean foo = true;

// bar is true
boolean bar = true;
<module name="Indentation">
    <property name="basicOffset" value="2"/>
    <property name="braceAdjustment" value="0"/>
    <property name="caseIndent" value="2"/>
    <property name="throwsIndent" value="4"/>
    <property name="lineWrappingIndentation" value="4"/>
    <property name="arrayInitIndent" value="2"/>
</module>

VIOLATION

/* <property name="basicOffset" value="2"/> */
class Foo {
    void bar() {
    }
}

/* <property name="braceAdjustment" value="0"/> */
void bar() {
    }

/* <property name="caseIndent" value="2"/> */
switch (foo) {
    case 0:
        break;
    case 1:
        break;
    default:
        break;
}

/* <property name="throwsIndent" value="4"/> */
public static void main(String[] args) throws
  IOException {
}

/* <property name="lineWrappingIndentation" value="4"/> */
if ((foo == bar)
  && (baz == qux)) {
    System.out.println("equal");
}

/* <property name="arrayInitIndent" value="2"/> */
int[] foo = {
    5,
    6
};

OK

/* <property name="basicOffset" value="2"/> */
class Foo {
  void bar() {
  }
}

/* <property name="braceAdjustment" value="0"/> */
void bar() {
}

/* <property name="caseIndent" value="2"/> */
switch (foo) {
  case 0:
    break;
  case 1:
    break;
  default:
    break;
}

/* <property name="throwsIndent" value="4"/> */
public static void main(String[] args) throws
    IOException {
}

/* <property name="lineWrappingIndentation" value="4"/> */
if ((foo == bar)
    && (baz == qux)) {
    System.out.println("equal");
}

/* <property name="arrayInitIndent" value="2"/> */
int[] foo = {
  5,
  6
};

파일의 맨 끝에 newline('\n')이 존재하는지 검사.

<module name="NewlineAtEndOfFile"/>

VIOLATION

1 class Foo {
2
3 }

OK

1 class Foo {
2 
3 }
4

파일 이름과 클래스명이 일치하는지 검사.

<module name="OuterTypeFilename"/>

VIOLATION

// Foo.java
class Bar {
}

OK

// Foo.java
class Foo {
}

long을 'l'이 아닌 'L'로 표현하는지를 검사.

<module name="UpperEll"/>

VIOLATION

long value = 100l // 1001?

OK

long value = 100L

modifier 순서를 검사.

  1. public
  2. protected
  3. private
  4. abstract
  5. default
  6. static
  7. final
  8. transient
  9. volatile
  10. synchronized
  11. native
  12. strictfp
<module name="ModifierOrder"/>

VIOLATION

abstract public void foo();

OK

public abstract void foo();

불필요한 modifier를 검사.

<module name="RedundantModifier"/>

VIOLATION

public interface Foo {
    public void bar();
}

OK

public interface Foo {
    void bar();
}

약어를 대문자로 표현했는지 검사.

<module name="AbbreviationAsWordInName">
    <property name="ignoreFinal" value="false"/>
    <property name="allowedAbbreviationLength" value="1"/>
    <property name="tokens"
              value="CLASS_DEF, INTERFACE_DEF, ENUM_DEF, ANNOTATION_DEF, ANNOTATION_FIELD_DEF,
                     PARAMETER_DEF, VARIABLE_DEF, METHOD_DEF"/>
</module>

VIOLATION

int firstFOO;
int secondFOo;

OK

int firstFoo;
int secondFoo;
String firstXML;    // abbreviation is allowed
String firstURL;    // abbreviation is allowed

catch 파라미터의 이름을 검사. "^[a-z]([a-z0-9][a-zA-Z0-9]*)?$" 패턴과 일치해야 한다.

<module name="CatchParameterName">
    <property name="format" value="^[a-z]([a-z0-9][a-zA-Z0-9]*)?$"/>
    <message key="name.invalidPattern"
             value="Catch parameter name ''{0}'' must match pattern ''{1}''."/>
</module>

VIOLATION

try {
} catch (ArithmeticException Foo) {
} catch (ArrayIndexOutOfBoundsException BAR2) {
}

OK

try {
} catch (ArithmeticException foo) {
} catch (ArrayIndexOutOfBoundsException bar2) {
}

클래스 제네릭 타입을 검사. "(^[A-Z][0-9]?)$|([A-Z][a-zA-Z0-9]*[T]$)" 패턴과 일치해야한다.

<module name="ClassTypeParameterName">
    <property name="format" value="(^[A-Z][0-9]?)$|([A-Z][a-zA-Z0-9]*[T]$)"/>
    <message key="name.invalidPattern"
             value="Class type name ''{0}'' must match pattern ''{1}''."/>
</module>

VIOLATION

class MyClass<t> { }

OK

class MyClass<T> { }

static final 변수 이름을 검사. "^[A-Z][A-Z0-9]*(_[A-Z0-9]+)*$" 패턴과 일치해야 한다.

<module name="ConstantName"/>

VIOLATION

public static final int foo = 100;

OK

public static final int FOO = 100;

interface 타입 이름을 검사. "(^[A-Z][0-9]?)$|([A-Z][a-zA-Z0-9]*[T]$)" 패턴과 일치해야 한다.

<module name="InterfaceTypeParameterName">
    <property name="format" value="(^[A-Z][0-9]?)$|([A-Z][a-zA-Z0-9]*[T]$)"/>
    <message key="name.invalidPattern"
             value="Interface type name ''{0}'' must match pattern ''{1}''."/>
</module>

VIOLATION

interface Foo<t> { }

OK

interface Foo<T> { }

람다의 파라미터 이름을 검사. "^[a-z]([a-z0-9][a-zA-Z0-9]*)?$" 패턴과 일치해야 한다.

<module name="LambdaParameterName">
    <property name="format" value="^[a-z]([a-z0-9][a-zA-Z0-9]*)?$"/>
    <message key="name.invalidPattern"
             value="Lambda parameter name ''{0}'' must match pattern ''{1}''."/>
</module>

VIOLATION

Function<String, String> foo = Bar -> Bar.toLowerCase();

OK

Function<String, String> foo = bar -> bar.toLowerCase();

지역 final 변수 이름을 검사. "^[a-z][a-zA-Z0-9]*$" 패턴과 일치해야한다.

<module name="LocalFinalVariableName">
    <property name="format" value="^[a-z]([a-z0-9][a-zA-Z0-9]*)?$"/>
        <message key="name.invalidPattern"
                 value="Local final variable name ''{0}'' must match pattern ''{1}''."/>
    </property>
</module>

VIOLATION

public void foo() {
    final int BAR = 100;
    final int Bar = 100;
}

OK

public void foo() {
    final int bar = 100;
}

지역 변수 이름을 검사. "^[a-z]([a-z0-9][a-zA-Z0-9]*)?$" 패턴과 일치해야한다.

<module name="LocalVariableName">
    <property name="format" value="^[a-z]([a-z0-9][a-zA-Z0-9]*)?$"/>
    <message key="name.invalidPattern"
             value="Local variable name ''{0}'' must match pattern ''{1}''."/>
</module>

VIOLATION

int foo_1;
int Foo1;
int FOO1;

OK

int fooBar1;

클래스 멤버 이름을 검사. "^[a-z][a-z0-9][a-zA-Z0-9]*$" 패턴과 일치해야한다.

<module name="MemberName">
    <property name="format" value="^[a-z][a-z0-9][a-zA-Z0-9]*$"/>
    <message key="name.invalidPattern"
             value="Member name ''{0}'' must match pattern ''{1}''."/>
</module>

VIOLATION

public int FOO1;
protected int FOO2;
final int FOO3;
private int FOO4;

OK

public int foo1;
protected int foo2;
final int foo3 = 3;
private int foo4;

/* static은 무시한다. */
static int FOO5 = 0;
static int foo6 = 0;

메소드 이름을 검사. "^[a-z][a-z0-9][a-zA-Z0-9_]*$" 패턴과 일치해야한다.

<module name="MethodName">
    <property name="format" value="^[a-z][a-z0-9][a-zA-Z0-9_]*$"/>
    <message key="name.invalidPattern"
             value="Method name ''{0}'' must match pattern ''{1}''."/>
</module>

VIOLATION

void Foo() { }

OK

void foo() { }

메소드 제네릭 타입 이름을 검사. "(^[A-Z][0-9]?)$|([A-Z][a-zA-Z0-9]*[T]$)" 패턴과 일치해야한다.

<module name="MethodTypeParameterName">
    <property name="format" value="(^[A-Z][0-9]?)$|([A-Z][a-zA-Z0-9]*[T]$)"/>
    <message key="name.invalidPattern"
             value="Method type name ''{0}'' must match pattern ''{1}''."/>
</module>

VIOLATION

public <t> void foo() { }

OK

public <T> void foo() { }

패키지 이름을 검사. "^[a-z]+(\.[a-z][a-z0-9]*)*$" 패턴과 일치해야한다.

<module name="PackageName">
    <property name="format" value="^[a-z]+(\.[a-z][a-z0-9]*)*$"/>
    <message key="name.invalidPattern"
             value="Package name ''{0}'' must match pattern ''{1}''."/>
</module>

VIOLATION

package FOO;
package foo.BAR.baz.qux;
package foo.fooBAR.bar;
package foo._bar.baz_;

OK

package foo;
package foo.bar.baz;
package foo.bar1.baz;

파라미터 이름을 검사. "^[a-z]([a-z0-9][a-zA-Z0-9]*)?$" 패턴과 일치해야한다.

<module name="ParameterName">
    <property name="format" value="^[a-z]([a-z0-9][a-zA-Z0-9]*)?$"/>
    <message key="name.invalidPattern"
             value="Parameter name ''{0}'' must match pattern ''{1}''."/>
</module>

VIOLATION

void foo(int bar_2) { }

void foo(int Bar3) { }

OK

void foo(int bar1) { }

static 변수 이름을 검사. "^[a-z][a-zA-Z0-9]*$" 패턴과 일치해야한다.

<module name="StaticVariableName">
    <property name="format" value="^[a-z][a-z0-9][a-zA-Z0-9]*$"/>
    <message key="name.invalidPattern"
             value="Static variable name ''{0}'' must match pattern ''{1}''."/>
</module>

VIOLATION

static int Foo = 300;
static int FOO = 300;

OK

static int foo = 300;

타입(class, interface, enum, annotation) 이름을 검사. "^[A-Z][a-zA-Z0-9]*$" 패턴과 일치해야한다.

<module name="TypeName">
    <property name="format" value="^[A-Z][a-zA-Z0-9]*$"/>
    <property name="tokens" value="CLASS_DEF, INTERFACE_DEF, ENUM_DEF, ANNOTATION_DEF"/>
    <message key="name.invalidPattern"
             value="Type name ''{0}'' must match pattern ''{1}''."/>
</module>

VIOLATION

class myClass { }

OK

class MyClass { }

라인 뒤에 공백(' ') 혹은 탭('\t') 문자가 존재하는지 검사.

<module name="Regexp">
    <property name="format" value="[ \t]+$"/>
    <property name="illegalPattern" value="true"/>
    <property name="message" value="Trailing whitespace"/>
</module>

한 파일이 2500 라인을 초과했는지 검사.

<module name="FileLength">
    <property name="max" value="2500"/>
</module>

한 라인에 100 캐릭터를 초과했는지 검사.

<module name="LineLength">
    <property name="fileExtensions" value="java"/>
    <property name="max" value="100"/>
    <property name="ignorePattern" value="^package.*|^import.*|a href|href|http://|https://|ftp://"/>
</module>

VIOLATION

String foo = "foooooooooooooooooooooooooooooooooooooooooooooooooooooooooo...";

OK

String foo = "fooooooooooooooooo" +
             "oooooooooooooooooo" +
             "ooooooooooooooo...";

메소드가 10000 라인을 초과했는지 검사.

<module name="MethodLength">
    <property name="max" value="10000"/>
</module>

파라미터 개수가 10개를 초과했는지 검사.

<module name="ParameterNumber">
    <property name="max" value="10"/>
</module>

VIOLATION

void foo(int a, int b, int c, int d, int e, int f, int g, int h, int i, int j) {
}

for loop의 공백을 검사.

<module name="EmptyForIteratorPad"/>

VIOLATION

int foo = 0;
for ( ; foo < 100; ) {
    foo++;
}

OK

int foo = 0;
for (; foo < 100;) {
    foo++;
}

packge, import 등의 줄 바꿈을 검사.

<module name="EmptyLineSeparator">
    <property name="tokens"
              value="PACKAGE_DEF, IMPORT, STATIC_IMPORT, CLASS_DEF, INTERFACE_DEF, ENUM_DEF,
                     STATIC_INIT, INSTANCE_INIT, METHOD_DEF, CTOR_DEF, VARIABLE_DEF"/>
    <property name="allowNoEmptyLineBetweenFields" value="true"/>
</module>

VIOLATION

package foo.bar.baz;
import foo.bar.baz.Qux;

public class Foo {
    public static void main(String[] args) {
    }
    public static void bar() {
    }
}

OK

package foo.bar.baz;

import foo.bar.baz.Qux;

public class Foo {
    public static void main(String[] args) {
    }

    public static void bar() {
    }
}

탭('\t') 문자가 존재하는지 검사.

<module name="FileTabCharacter">
    <property name="eachLine" value="true"/>
</module>

제네릭의 공백 규칙을 검사.

<module name="GenericWhitespace">
    <message key="ws.followed"
             value="GenericWhitespace ''{0}'' is followed by whitespace."/>
    <message key="ws.preceded"
             value="GenericWhitespace ''{0}'' is preceded with whitespace."/>
    <message key="ws.illegalFollow"
             value="GenericWhitespace ''{0}'' should followed by whitespace."/>
    <message key="ws.notPreceded"
             value="GenericWhitespace ''{0}'' is not preceded with whitespace."/>
</module>

VIOLATION

List <String> foo;
List<String>bar;
List< String> baz;
List<String > qux;

public< X, Y >X quux(X x, Y y) {
    return ...;
}

OK

List<String> foo;

public <X, Y> X bar(X x, Y y) {
    return ...;
}

메소드와 파라미터 사이의 공백을 검사.

<module name="MethodParamPad">
    <property name="tokens"
              value="CTOR_DEF, LITERAL_NEW, METHOD_CALL, METHOD_DEF,
                     SUPER_CTOR_CALL, ENUM_CONSTANT_DEF"/>
</module>

VIOLATION

public void foo (int bar) {
    Baz baz = new Baz ();
    baz.qux (1);
}

OK

public void foo(int bar) {
    Baz baz = new Baz();
    baz.qux(1);
}

import의 줄바꿈을 검사.

<module name="NoLineWrap">
    <property name="tokens" value="PACKAGE_DEF, IMPORT, STATIC_IMPORT"/>
</module>

VIOLATION

package foo.bar.
        baz.qux;
import foo.bar.
        baz.Qux;
import static foo.bar.
        Baz.QUX;

OK

package foo.bar.baz.qux;
import foo.bar.baz.Qux;
import static foo.bar.Baz.QUX;

토큰 뒤의 공백을 검사.

<module name="NoWhitespaceAfter"/>

VIOLATION

if (! foo) {
    ++ bar;
}

OK

if (!foo) {
    ++bar;
}

토큰 앞의 공백을 검사.

<module name="NoWhitespaceBefore"/>

VIOLATION

int foo = 0 ;
foo ++;
this .bar(1, 2, 3);
this.bar(1 , 2 , 3);

OK

int foo = 0;
foo++;
this.bar(1, 2, 3);

연산자의 줄바꿈을 검사.

<module name="OperatorWrap">
    <property name="option" value="NL"/>
    <property name="tokens"
              value="BAND, BOR, BSR, BXOR, DIV, EQUAL, GE, GT, LAND, LE, LITERAL_INSTANCEOF,   
                     LOR, LT, MINUS, MOD, NOT_EQUAL, PLUS, QUESTION, SL, SR, STAR, METHOD_REF"/>
</module>

VIOLATION

String foo = "A" +
    "B";

if ((bar == baz) &&
    (qux == quux)) {
    System.out.println("equal");
}

OK

String foo = "A"
    + "B";

if ((bar == baz)
    && (qux == quux)) {
    System.out.println("equal");
}

괄호 사이의 공백을 검사.

<module name="ParenPad">
    <property name="tokens"
              value="ANNOTATION, ANNOTATION_FIELD_DEF, CTOR_CALL, CTOR_DEF, DOT,          
                     ENUM_CONSTANT_DEF,
                     EXPR, LITERAL_CATCH, LITERAL_DO, LITERAL_FOR, LITERAL_IF, LITERAL_NEW,
                     LITERAL_SWITCH, LITERAL_SYNCHRONIZED, LITERAL_WHILE, METHOD_CALL,
                     METHOD_DEF, QUESTION, RESOURCE_SPECIFICATION, SUPER_CTOR_CALL, LAMBDA"/>
</module>

VIOLATION

new String( "foo" );
this.bar( "bar" );

OK

new String("foo");
this.bar("bar");

dot('.')이 개행문자 뒤에 존재하는지 검사.

<module name="SeparatorWrap">
    <property name="id" value="SeparatorWrapDot"/>
    <property name="tokens" value="DOT"/>
    <property name="option" value="nl"/>
</module>

VIOLATION

new Foo().
    bar(null).
    baz();

OK

new Foo()
    .bar(null)
    .baz();

comma가 개행문자 앞에 존재하는지 검사.

<module name="SeparatorWrap">
    <property name="id" value="SeparatorWrapComma"/>
    <property name="tokens" value="COMMA"/>
    <property name="option" value="EOL"/>
</module>

VIOLATION

System.out.printf(
    "%d %d %d"
    ,1
    ,2
    ,3
);

OK

System.out.printf(
    "%d %d %d",
    1,
    2,
    3
);

ellipsis('...')가 개행문자 앞에 존재하는지 검사.

<module name="SeparatorWrap">
    <property name="id" value="SeparatorWrapEllipsis"/>
    <property name="tokens" value="ELLIPSIS"/>
    <property name="option" value="EOL"/>
</module>

VIOLATION

public static void printf(
    String
        arg1,
    Object
        ...arg2) { }

OK

public static void printf(
    String
        arg1,
    Object...
        arg2) { }

배열 선언 문자('[', ']')가 개행문자 앞에 존재하는지 검사.

<module name="SeparatorWrap">
    <property name="id" value="SeparatorWrapArrayDeclarator"/>
    <property name="tokens" value="ARRAY_DECLARATOR"/>
    <property name="option" value="EOL"/>
</module>

VIOLATION

int
    []array;

OK

int[]
    array;

메소드 참조('::') 문자가 개행문자 뒤에 존재하는지 검사.

<module name="SeparatorWrap">
    <property name="id" value="SeparatorWrapMethodRef"/>
    <property name="tokens" value="METHOD_REF"/>
    <property name="option" value="nl"/>
</module>

VIOLATION

Arrays.sort(stringArray, String::
    compareToIgnoreCase);

OK

Arrays.sort(stringArray, String
    ::compareToIgnoreCase);

타입 변환 괄호 사이의 공백을 검사.

<module name="TypecastParenPad"/>

VIOLATION

foo = ( String ) bar;

OK

foo = (String) bar;

comma(','), semi-colon(';') 뒤의 공백을 검사.

<module name="WhitespaceAfter">
    <property name="tokens" value="COMMA, SEMI"/>
</module>

VIOLATION

void foo(int bar,int baz) {
}

OK

void foo(int bar, int baz) {
}

token 사이에 공백이 존재하는지 검사.

<module name="WhitespaceAround">
    <property name="allowEmptyConstructors" value="true"/>
    <property name="allowEmptyLambdas" value="true"/>
    <property name="allowEmptyMethods" value="false"/>
    <property name="allowEmptyTypes" value="true"/>
    <property name="allowEmptyLoops" value="true"/>
    <property name="tokens"
              value="ASSIGN, BAND, BAND_ASSIGN, BOR, BOR_ASSIGN, BSR, BSR_ASSIGN, 
                     BXOR, BXOR_ASSIGN, COLON, DIV, DIV_ASSIGN, DO_WHILE, EQUAL, 
                     GE, GT, LAMBDA, LAND,LCURLY, LE, LITERAL_CATCH, LITERAL_DO, 
                     LITERAL_ELSE, LITERAL_FINALLY,LITERAL_FOR, LITERAL_IF, 
                     LITERAL_RETURN, LITERAL_SWITCH, LITERAL_SYNCHRONIZED,
                     LITERAL_TRY, LITERAL_WHILE, LOR, LT, MINUS, MINUS_ASSIGN, 
                     MOD, MOD_ASSIGN, NOT_EQUAL, PLUS, PLUS_ASSIGN, QUESTION, 
                     RCURLY, SL, SLIST, SL_ASSIGN, SR, SR_ASSIGN, STAR, 
                     STAR_ASSIGN, LITERAL_ASSERT, TYPE_EXTENSION_AND"/>
    <message key="ws.notFollowed"
             value="WhitespaceAround: ''{0}'' is not followed by whitespace. Empty blocks may only be represented as '{}' when not part of a multi-block statement (4.1.3)"/>
    <message key="ws.notPreceded"
             value="WhitespaceAround: ''{0}'' is not preceded with whitespace."/>
</module>

VIOLATION

boolean result = foo==bar;     // '==' must preceded and followed whitespace

while(true) {}                // 'while' must followed by whitespace

if(foo == bar) { }            // 'if' is not followed by whitespace

System.out.println(foo+bar);  // '+' must preceded and followed whitespace

synchronized(this) {}         // 'synchronized' must followed by whitespace

OK

boolean result = foo == bar;

while (true) {}

if (foo == bar) { }

System.out.println(foo + bar);

synchronized (this) {}