Skip to content
This repository has been archived by the owner on Jan 22, 2023. It is now read-only.

kemitix/kemitix-checkstyle-ruleset

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

kemitix-checkstyle-ruleset

Provides an extensive Checkstyle ruleset for use with Checkstyle, together with a fully configured maven-tile.

GitHub release (latest by date) GitHub Release Date

Sonatype Nexus (Release) Maven Central

The ruleset includes checks from both the core Checkstyle library and from the Sevntu-Checkstyle library.

Usage

The simplest way to use the ruleset is with the maven-tile:

<project>
    <properties>
        <tiles-maven-plugin.version>2.11</tiles-maven-plugin.version>
    </properties>
    <build>
        <plugins>
            <plugin>
                <groupId>io.repaint.maven</groupId>
                <artifactId>tiles-maven-plugin</artifactId>
                 <version>${tiles-maven-plugin.version}</version>
                <extensions>true</extensions>
                <configuration>
                    <tiles>
                        <tile>net.kemitix.checkstyle:tile:${version}</tile>
                    </tiles>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

The following levels implement increasingly strict rulesets:

  • 0-disabled
  • 1-layout
  • 2-naming
  • 3-javadoc
  • 4-tweaks
  • 5-complexity

The default ruleset from the maven-tile is 5-complexity. Other levels can be selected by setting the kemitix.checkstyle.ruleset.level to one the values above.

Change from 4.x

The RedundantModifier rule has been replaced by the InterfaceMemberImpliedModifier. This is to ensure that intefaces in Java 9+ are easier to comprehend with the addition of private methods. The rules governing the implied modifiers for members of interfaces differs from those of classes. So, to remove the need to remember the different rules, they are now required to be explicitly stated.

Change from 3.x

Rename the artifact net.kemitix:kemitix-checkstyle-ruleset as net.kemitix.checkstyle:ruleset.

Introduction of the artifact net.kemitix.checkstyle:tile for use with the tiles-maven-plugin.

Change from 2.x

In 2.x, the level was specified as the goal to invoke. In 3.x, there is only the 'check' goal. The level is now specified as a configuration parameter. See the example below. The kemitix-checkstyle-maven-plugin has also been removed in favour of the maven-tile.

All Checks

Rule Level Source Enabled Suppressible
AbbreviationAsWordInName naming checkstyle Yes
AbstractClassName naming checkstyle
AnnotationLocation layout checkstyle Yes
AnnotationUseStyle layout checkstyle Yes
AnonInnerLength complexity checkstyle Yes
ArrayTrailingComma tweaks checkstyle
ArrayTypeStyle layout checkstyle Yes
AtclauseOrder javadoc checkstyle Yes
AvoidConditionInversion complexity sevntu
AvoidConstantAsFirstOperandInCondition tweaks sevntu Yes
AvoidDefaultSerializableInInnerClasses tweaks sevntu Yes
AvoidDoubleBraceInitialization tweaks checkstyle Yes
AvoidEscapedUnicodeCharacters tweaks checkstyle Yes
AvoidHidingCauseException tweaks sevntu Yes
AvoidInlineConditionals complexity checkstyle Yes
AvoidModifiersForTypes unspecified sevntu
AvoidNestedBlocks complexity checkstyle Yes
AvoidNoArgumentSuperConstructorCall tweaks checkstyle Yes
AvoidNotShortCircuitOperatorsForBoolean tweaks sevntu Yes
AvoidStarImport layout checkstyle
AvoidStaticImport complexity checkstyle
BooleanExpressionComplexity complexity checkstyle Yes
CatchParameterName naming checkstyle Yes
CauseParameterInException tweaks sevntu
ChildBlockLength complexity sevntu
ClassDataAbstractionCoupling complexity checkstyle Yes
ClassFanOutComplexity complexity checkstyle Yes
ClassTypeParameterName naming checkstyle Yes
CommentsIndentation layout checkstyle Yes
ConfusingCondition complexity sevntu Yes
ConstantName naming checkstyle Yes No
ConstructorWithoutParams complexity sevntu Yes
CovariantEquals complexity checkstyle Yes No
CustomDeclarationOrder layout sevntu
CyclomaticComplexity complexity checkstyle Yes
DeclarationOrder layout checkstyle Yes
DefaultComesLast tweaks checkstyle Yes
DesignForExtension complexity checkstyle Yes
DiamondOperatorForVariableDefinition tweaks sevntu Yes
EitherLogOrThrow tweaks sevntu Yes
EmptyBlock tweaks checkstyle Yes
EmptyCatchBlock tweaks checkstyle Yes
EmptyForInitializerPad layout checkstyle Yes
EmptyForIteratorPad layout checkstyle Yes
EmptyLineSeparator layout checkstyle
EmptyPublicCtorInClass tweaks sevntu Yes
EmptyStatement layout checkstyle Yes
EnumValueName naming sevntu Yes
EqualsAvoidNull tweaks checkstyle Yes
EqualsHashCode complexity checkstyle Yes No
ExecutableStatementCount complexity checkstyle Yes
ExplicitInitialization tweaks checkstyle Yes
FallThrough javadoc checkstyle Yes
FileLength complexity checkstyle Yes
FileTabCharacter layout checkstyle Yes
FinalClass complexity checkstyle Yes
FinalizeImplementation tweaks sevntu Yes
FinalLocalVariable tweaks checkstyle
FinalParameters tweaks checkstyle Yes
ForbidAnnotation unspecified sevntu
ForbidCCommentsInMethods layout sevntu Yes
ForbidCertainImports unspecified sevntu
ForbidInstantiation unspecified sevntu
ForbidReturnInFinallyBlock complexity sevntu Yes
ForbidThrowAnonymousExceptions tweaks sevntu
ForbidWildcardAsReturnType complexity sevntu Yes
GenericWhitespace layout checkstyle Yes
Header layout checkstyle
HiddenField tweaks checkstyle Yes
HideUtilityClassConstructor tweaks checkstyle Yes
IllegalCatch tweaks checkstyle Yes
IllegalImport tweaks checkstyle Yes
IllegalInstantiation unspecified checkstyle
IllegalThrows tweaks checkstyle Yes
IllegalToken tweaks checkstyle Yes
IllegalTokenText unspecified checkstyle
IllegalType tweaks checkstyle Yes
ImportControl unspecified checkstyle
ImportOrder layout checkstyle
Indentation layout checkstyle
InnerAssignment tweaks checkstyle Yes
InnerTypeLast tweaks checkstyle Yes
InterfaceIsType complexity checkstyle Yes
InterfaceMemberImpliedModifier tweaks checkstyle
InterfaceTypeParameterName naming checkstyle Yes
JavadocMethod javadoc checkstyle
JavadocMissingLeadingAsterisk javadoc checkstyle Yes
JavadocMissingWhitespaceAfterAsterisk javadoc checkstyle Yes
JavadocPackage javadoc checkstyle Yes
JavadocParagraph javadoc checkstyle Yes
JavadocStyle javadoc checkstyle Yes
JavadocTagContinuationIndentation layout checkstyle
JavadocType javadoc checkstyle Yes
JavadocVariable javadoc checkstyle
JavaNCSS complexity checkstyle Yes
LambdaBodyLength complexity checkstyle Yes
LambdaParameterName naming checkstyle Yes
LeftCurly layout checkstyle Yes
LineLength layout checkstyle Yes
LocalFinalVariableName naming checkstyle Yes
LocalVariableName naming checkstyle Yes
LogicConditionNeedOptimization tweaks sevntu Yes
MagicNumber naming checkstyle Yes
MapIterationInForEachLoop complexity sevntu Yes
MemberName naming checkstyle Yes
MethodCount complexity checkstyle Yes
MethodLength complexity checkstyle Yes
MethodName naming checkstyle Yes
MethodParamPad layout checkstyle Yes
MethodTypeParameterName naming checkstyle Yes
MissingCtor tweaks checkstyle
MissingDeprecated javadoc checkstyle Yes
MissingOverride tweaks checkstyle
MissingSwitchDefault tweaks checkstyle Yes
ModifiedControlVariable tweaks checkstyle Yes
ModifierOrder naming checkstyle Yes
MoveVariableInsideIfCheck tweaks sevntu Yes
MultipleStringLiterals naming checkstyle Yes
MultipleVariableDeclarations naming checkstyle Yes
MutableException tweaks checkstyle Yes
NameConventionForJunit4TestClasses naming sevntu Yes
NeedBraces naming checkstyle Yes
NestedForDepth complexity checkstyle Yes
NestedIfDepth complexity checkstyle Yes
NestedSwitch complexity sevntu Yes
NestedTryDepth complexity checkstyle Yes
NewlineAtEndOfFile layout checkstyle Yes
NoClone tweaks checkstyle Yes No
NoCodeInFile layout checkstyle Yes
NoFinalizer tweaks checkstyle Yes
NoLineWrap layout checkstyle Yes
NoMainMethodInAbstractClass tweaks sevntu Yes
NonEmptyAtclauseDescription javadoc checkstyle Yes
NoWhitespaceAfter layout checkstyle Yes
NoWhitespaceBefore layout checkstyle Yes
NoWhitespaceBeforeCaseDefaultColon layout checkstyle Yes
NPathComplexity complexity checkstyle Yes
NumericLiteralNeedsUnderscore naming sevntu Yes
OneStatementPerLine layout checkstyle Yes
OneTopLevelClass tweaks checkstyle Yes No
OperatorWrap layout checkstyle Yes
OuterTypeFilename tweaks checkstyle Yes No
OuterTypeNumber tweaks checkstyle
OverloadMethodsDeclarationOrder layout checkstyle Yes
OverridableMethodInConstructor tweaks sevntu Yes
PackageAnnotation tweaks checkstyle Yes
PackageDeclaration javadoc checkstyle Yes No
PackageName naming checkstyle Yes
ParameterAssignment tweaks checkstyle
ParameterName naming checkstyle Yes
ParameterNumber complexity checkstyle Yes
ParenPad layout checkstyle Yes
PublicReferenceToPrivateType tweaks sevntu Yes
RedundantImport layout checkstyle
RedundantModifier tweaks checkstyle
RedundantReturn tweaks sevntu Yes
Regexp unspecified checkstyle
RegexpHeader unspecified checkstyle
RegexpMultiline unspecified checkstyle
RegexpOnFilename layout checkstyle Yes
RegexpOnFilename unspecified checkstyle
RegexpSingleline unspecified checkstyle
RegexpSinglelineJava unspecified checkstyle
RequiredParameterForAnnotation unspecified sevntu
RequireThis tweaks checkstyle Yes
ReturnBooleanFromTernary tweaks sevntu Yes
ReturnCount complexity checkstyle Yes
ReturnNullInsteadOfBoolean tweaks sevntu Yes
RightCurly layout checkstyle Yes
SeparatorWrap layout checkstyle Yes
SimpleAccessorNameNotation naming sevntu
SimplifyBooleanExpression complexity checkstyle Yes
SimplifyBooleanReturn complexity checkstyle Yes
SingleBreakOrContinue tweaks sevntu Yes
SingleLineJavadoc javadoc checkstyle
SingleSpaceSeparator layout checkstyle Yes
StaticMethodCandidate unspecified sevntu
StaticVariableName naming checkstyle Yes
StringLiteralEquality tweaks checkstyle Yes
SummaryJavadoc javadoc checkstyle
SuperClone tweaks checkstyle
SuperFinalize tweaks checkstyle
SuppressWarnings naming checkstyle Yes
SuppressWarningsFilter naming checkstyle Yes
SuppressWarningsHolder naming checkstyle Yes
TernaryPerExpressionCount tweaks sevntu Yes
ThrowsCount complexity checkstyle Yes
TodoComment javadoc checkstyle Yes
TrailingComment layout checkstyle Yes
Translation javadoc checkstyle Yes
TypecastParenPad layout checkstyle Yes
TypeName naming checkstyle Yes No
UncommentedMain javadoc checkstyle Yes
UniformEnumConstantName naming sevntu Yes
UniqueProperties javadoc checkstyle Yes
UnnecessaryParentheses layout checkstyle Yes
UnnecessarySemicolonAfterOuterTypeDeclaration layout checkstyle Yes
UnusedImports layout checkstyle Yes
UpperEll layout checkstyle Yes
UselessSingleCatch tweaks sevntu Yes
UselessSuperCtorCall tweaks sevntu Yes
VariableDeclarationUsageDistance tweaks checkstyle Yes
VisibilityModifier tweaks checkstyle Yes No
WhitespaceAfter layout checkstyle Yes
WhitespaceAround layout checkstyle Yes
WhitespaceBeforeArrayInitializer layout sevntu Yes
WriteTag unspecified checkstyle

Enabled Checks

The following is a list of each of the checks and the expectations each has on your code.

Checkstyle

Rules are listed in alphabetical order.

Enforces proper CamelCase and avoids sequences of consecutive uppercase characters in identifiers. Does not apply to @Overridden methods.

Valid:

class DaoManager {}

Invalid:

class DAOManager {}

Annotations must be on a line by themselves unless annotating a method parameter or among class modifiers.

Valid:

@Component
@Qualifier("Red")
class RedStick implements Stick {

    public @NonNull String getLabel(@Value("${stick.length}") final int length) {
        // ...
    }
}

Invalid:

@Component @Qualifier("Red")
class RedStick implements Stick {}

Annotations should only use brackets and named attributes when they are needed. If only the default parameter is specified, then only the attribute value should be given. If there are no parameters, then no brackets should be given.

Valid:

@Entity
@Table("names")
@MyAnnotation(realm = "external")

Invalid:

@Entity()
@Table(value = "names")

Anonymous inner classes should be no more than 20 lines.

Enforces Java style arrays.

Valid:

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

Invalid:

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

Javadoc @ clauses must be in the order:

/**
 *
 * @param ...
 * @author ...
 * @version ...
 * @serial ...
 * @return ...
 * @throws ...
 * @exception ...
 * @serialData ...
 * @serialField ...
 * @see ...
 * @since ...
 * @deprecated ...
 */

Detects double brace initialization.

Rationale: Double brace initialization (set of Instance Initializers in class body) may look cool, but it is considered as anti-pattern and should be avoided. This is also can lead to a hard-to-detect memory leak, if the anonymous class instance is returned outside and other object(s) hold reference to it. Created anonymous class is not static, it holds an implicit reference to the outer class instance. See this blog post and article for more details. Check ignores any comments and semicolons in class body.

Invalid:

class MyClass {
    List<Integer> list1 = new ArrayList<>() { // violation
        {
            add(1);
        }
    };
    List<String> list2 = new ArrayList<>() { // violation
        ;
        // comments and semicolons are ignored
        {
            add("foo");
        }
    };
}

Prevents use of obscure escape codes (e.g. \u221e). However, non-printable/control characters are still permitted.

Valid:

String unitAbbrev = "??s";
String byteOrdered = '\ufeff' = content;

Invalid:

String unitAbbrev = "\u03bcs";

Prevents use of the ?: operators.

Avoid unnecessary blocks.

Valid:

if (isDebug()) {
    // ...
}

Invalid:

// if (isDebug())
{
    // ...
}

Checks if call to superclass constructor without arguments is present. Such invocation is redundant because constructor body implicitly begins with a superclass constructor invocation super(); See specification for detailed information.

Valid:

class MyClass extends SomeOtherClass {
    MyClass(int arg) {
        super(arg); // OK, call with argument have to be explicit
    }
    MyClass(long arg) {
        // OK, call is implicit
    }
}

Invalid:

class MyClass extends SomeOtherClass {
    MyClass() {
        super(); // violation
    }
}

Restrict the number of number of &&, ||, &, | and ^ in an expression to 2.

Valid:

if (a || (b && c)) {}

Invalid:

if (a > b || b > c || c == a || d > a) {}

Checks that catch parameter names conform to the following characteristic:

  • allows names beginning with two lowercase letters followed by at least one uppercase or lowercase letter
  • allows e abbreviation (suitable for exceptions end errors)
  • allows ex abbreviation (suitable for exceptions)
  • allows t abbreviation (suitable for throwables)
  • prohibits numbered abbreviations like e1 or t2
  • prohibits one letter prefixes like pException
  • prohibits two letter abbreviations like ie or ee
  • prohibits any other characters than letters

Valid:

catch(Exception txD) {}
catch(Exception txf) {}
catch(Exception e) {}
catch(Error e) {}
catch(Exception ex) {}
catch(Throwable t) {}

Invalid:

catch(Exception e2) {}
catch(Exception pExceptions) {}
catch(Exception gh) {}
catch(Exception e_x) {}

Restricts to 7 the number of different classes instantiated within a class when that class is instantiated.

Valid:

class Valid {
    private final Item i1 = new Item();
    private final Item i2 = new Item();
    private final Item i3 = new Item();
    private final Item i4 = new Item();
    private final Item i5 = new Item();
    private final Item i6 = new Item();
    private final Item i7 = new Item();
    private final Item i8 = new Item();
}

Invalid:

class Invalid {
    private final ItemA i1 = new ItemA();
    private final ItemB i2 = new ItemB();
    private final ItemC i3 = new ItemC();
    private final ItemD i4 = new ItemD();
    private final ItemE i5 = new ItemE();
    private final ItemF i6 = new ItemF();
    private final ItemG i7 = new ItemG();
    private final ItemH i8 = new ItemH();
}

Restricts the number of other classes that a class can rely on to 20.

While ClassDataAbstractionCoupling limits the number of classes that are instantiated when the class is, this check counts all fields whether they are assigned a value or not.

Restricts class generics parameters to be a single uppercase letter.

Valid:

class Deliverator <A> {}

Invalid:

class Invalidator <a> {}
class Invalidator <BB> {}
class Invalidator <C3> {}

Requires the indentation of comments to match the surrounding code.

Valid:

/**
 * This is okay.
 */
int size = 20;

public foo() {
    super();
    // this is okay
}

public void foo11() {
    CheckUtils
        .getFirstNode(new DetailAST())
        .getFirstChild()
        .getNextSibling();
    // this is okay
}

Invalid:

    /**
     * This is NOT okay.
     */
int size = 20;

public foo() {
    super();
        // this is NOT okay
// this is NOT okay
}

public void foo11() {
    CheckUtils
        .getFirstNode(new DetailAST())
        .getFirstChild()
        .getNextSibling();
            // this is NOT okay
}

This check cannot be suppressed.

Requires constants (static, final fields) to be all uppercase. Numbers and numbers are permitted but not as the first character.

Valid:

private static final int JACK_CARD = 11;

Invalid:

private static final int ace_card = 1;
private static final int 12_CARD = 12;

This check cannot be suppressed.

Checks that classes which define a covariant equals() method also override method equals(Object).

Valid:

class Test {
    public boolean equals(Test i) {
        return false;
    }

    public boolean equals(Object i) {
       return false;
    }
}

Invalid:

class Test {
    public boolean equals(Test i) {
        return false;
    }
}

Restricts the cyclomatic complexity of a method to 5. The cyclomatic complexity is a measure of the number of decision points in a method.

A method with no branches has a complexity of 1. For each if, while, do, for, ?:, catch, switch, case, && and || the complexity goes up by 1.

Valid:

void isValid(int a, int b, int c) {
    // 1
    if (a > b) { // +1 = 2
        switch (c) { // +1 = 3
            case 1: // +1 = 4
                break;
            case 2: // +1 = 5
                break;
        }
    }
}

Invalid:

void isInvalid(int a, int b, int c) {
    // 1
    if (a > b) { // +1 = 2
        switch (c) { // +1 = 3
            case 1: // +1 = 4
                break;
            case 2: // +1 = 5
                break;
            case 3: // +1 = 6
                break;
        }
    }
}

Ensure class elements appear in the correct order.

Valid:

class Valid {
    // static
    public static int a;
    protected static int b;
    static int c;
    private static int d;

    // instance
    public int e;
    protected int f;
    int g;
    private int h;

    // constructors
    Valid() {}

    // methods
    void foo() {}
}

Invalid:

class Invalid {
    protected static int b;
    public static int a;
    private static int d;

    public int e;
    static int c;
    protected int f;
    private int h;

    void foo() {}

    Valid() {}

    int g;
}

Check that the default is after all the cases in a switch statement.

Valid:

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

Invalid:

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

Judicous use of @SuppressWarnings("designdorextension") is recommended for this check.

This check is primarily intended for use in library modules rather than applications.

Classes that are deemed by their designer to be 'designed for extension', must take steps to prevent a subclass from breaking the class's behaviour by overriding methods incorrectly. This can be done through a combination of:

  • Defining 'hook' methods with empty implementations that subclasses override to add their own behaviour
  • Marking methods that are non-private and non-static as abstract or final

See the official Checkstyle documentation for more details and Effective Java, 2nd Edition by Josh Bloch: Item 17: Design and document for inheritance or else prohibit it.

Checks for empty blocks.

Valid:

if (a >b) {
	doSomething();
}

Invalid:

if (a > b) {
}

Checks that catch blocks are not empty, or are commented with the word expected or ignore.

Valid:

try {
    something();
} catch (Exception e) {
    // ignore
}

Invalid:

try {
    something();
} catch (Exception e) {
    // do nothing
}

Checks that there is no padding in an empty for loop initialiser.

Valid:

for (; i < j ; i++) {}

Invalid:

for ( ; i < j ; i++) {}

Checks that there is no padding in an empty for loop iterator.

Valid:

for (Iterator i = list.getIterator(); i.hasNext() ;) {}

Invalid:

for (Iterator i = list.getIterator(); i.hasNext() ; ) {}

Checks for empty statements. An empty statement is a standalone semicolon (;).

Valid:

doSomething();

Invalid:

doSomething();;

Checks that string literals are on the left side in an equals() comparison.

Valid:

String nullString = null;
"value".equals(nullString);

Invalid:

String nullString = null;
nullString.equals("value");

This check cannot be suppressed.

Checks that when a class overrides the equals() method, that it also overrides the hashCode() method.

Limits the number of executable statements in a method to 30.

Checks that object fields are not being explicitly initialised to their already default value.

Does not check primitive field types.

Valid:

class Valid {

    private int foo = 0;

    private Object bar;
}

Invalid:

class Invalid {

    private Integer foo = 0;

    private Object bar = null;
}

Checks that when a case in a switch statement falls through (i.e. doesn't end with break;) that the fall through is documented with a comment.

Valid:

switch (i) {
    case 0:
        i++; // fall through

    case 1:
        i++;
        // falls through

    case 2:
    case 3:
    case 4: { i++ } // fallthrough
    case 5:
        i++;
        /* fallthrou */
    case 6:
        i++;
        break;
}

Invalid:

switch (i) {
    case 0:
        i++;
    case 1:
        i++;
    case 2:
    case 3:
    case 4: { i++ }
    case 5:
        i++;
    case 6:
        i++;
        break;
}

Checks that each file has no more than 2000 lines.

Checks that there are no tab characters in the source files.

Checks that classes which have only private constructors are also declared as final. These classes can't be extended by a subclass as they can't call super() from their constructors.

Valid:

final class Valid {

    private Valid() {}
}

Invalid:

class Invalid {

    private Invalid() {}
}

Parameters to a method must be final.

Valid:

void foo(final int a) {}

Invalid:

void foo(int a) {}

Checks that the angle brackets around Generics parameters have the correct whitespace padding:

Valid:

public void <K, V extends Number> boolean foo(K, V) {}
class name<T1, T2, ..., Tn> {}
OrderedPair<String, Box<Integer>> p;
boolean same = Util.<Integer, String>compare(p1, p2);
Pair<Integer, String> p1 = new Pair<>(1, "apple");
List<T> list = ImmutableList.Builder<T>::new;
sort(list, Comparable::<String>compareTo);

Checks that a local variable or parameter in a method doesn't have the same name as a field. Doesn't apply in constructors or setters.

Valid:

class Foo {

    private int a;

    Foo(int a) {
        this.a = a;
    }

    setA(int a) {
        this.a = a;
    }
}

Invalid:

class Bar {

    private int b;

    void baz(int b) {
        // ...
    }
}

Classes that only have static fields or methods should not have a public constructor. This includes the default constructor.

Valid:

final class StringUtils {

    private Utils() {}

    private static int count(chat c, String s) {}
}

class StringUtils {

    protected Utils() {
        throw new UnsupportedOperationException();
    }

    private static int count(chat c, String s) {}
}

Invalid:

class StringUtils {

    private static int count(chat c, String s) {}
}

Prevent the following types from being in a catch statement:

  • java.lang.Exception
  • java.lang.Throwable
  • java.lang.RuntimeException

Valid:

try {
    doSomething();
} catch (SpecificException e) {
    // log
}

Invalid:

try {
    doSomething();
} catch (Exception e) {
    // log
}

Prevent importing from the sun.* packages.

Invalid:

import sun.security.provider.Sun;

Prevent the following types from being thrown:

  • java.lang.Exception
  • java.lang.Throwable
  • java.lang.RuntimeException

Valid:

throw new SpecificException("error");

Invalid:

throw new RuntimeException("boom!");

Checks that labels are not used.

Prevents use of implementation classes as variables, parameters or method returns. Use the interfaces instead.

Prevents variables, parameters and method returns from being any of the following:

  • java.util.ArrayDeque
  • java.util.ArrayList
  • java.util.EnumMap
  • java.util.EnumSet
  • java.util.HashMap
  • java.util.HashSet
  • java.util.IdentityHashMap
  • java.util.LinkedHashMap
  • java.util.LinkedHashSet
  • java.util.LinkedList
  • java.util.PriorityQueue
  • java.util.TreeMap
  • java.util.TreeSet

Valid:

Set<String> getNames();

Invalid:

HashSet<String> getNames();

Checks for assignments within an expressions. However, it still allows assignment in a while loop clause.

Valid:

while((line = reader.readLine()) != null) {
}

Invalid:

String s = Integer.toString(i = 2);

Inner classes must appear at the bottom of a class, below fields and methods.

An interface must define methods, not just constants.

Valid:

interface Foo {

    static final String "Foo!!";

    getBar();
}

Invalid:

interface Foo {

    static final String "Foo!!";
}

Checks that the type parameters for an interface are a single uppercase letter.

Valid:

interface <T> Portable {}

Invalid:

interface <Type> Portable {}

Checks if the javadoc has leading asterisks on each line.

The check does not require asterisks on the first line, nor on the last line if it is blank. All other lines in a Javadoc should start with *, including blank lines and code blocks.

Valid:

/**
 * Valid Java-style comment.
 *
 * <pre>
 *   int value = 0;
 * </pre>
 */
class JavaStyle {} // ok

/** Valid Scala-style comment.
  * Some description here.
  **/
class ScalaStyle {} // ok

/** **
  * Asterisks on first and last lines are optional.
  * */
class Asterisks {} // ok

/** No asterisks are required for single-line comments. */
class SingleLine {} // ok

Invalid:

/** // violation on next blank line, javadoc has lines without leading asterisk.

 */
class BlankLine {}

/** Wrapped
    single-line comment */ // violation, javadoc has lines without leading asterisk.
class Wrapped {}

/**
  * <pre>
    int value; // violation, javadoc has lines without leading asterisk.
  * </pre>
  */
class Code {}

Checks that there is at least one whitespace after the leading asterisk. Although spaces after asterisks are optional in the Javadoc comments, their absence makes the documentation difficult to read. It is the de facto standard to put at least one whitespace after the leading asterisk.

Valid:

/** This is valid single-line Javadoc. */
class TestClass {
  /**
   * This is valid Javadoc.
   */
  void validJavaDocMethod() {
  }
  /** This is valid single-line Javadoc. */
  void validSingleLineJavaDocMethod() {
  }
}

Invalid:

class TestClass {
  /**
   *This is invalid Javadoc.
   */
  int invalidJavaDoc;
  /**This is invalid single-line Javadoc. */
  void invalidSingleLineJavaDocMethod() {
  }
}

Checks that each package has a package-info.java file.

Checks that paragraphs in Javadoc blocks are wrapped in <p> elements and have blank lines between paragraphs. This first paragraph does not need the <p> elements.

Checks the formatting of the Javadoc blocks. See the official Checkstyle documentation for all the checks that are applied.

Checks the format for Javadoc for classes and enums. Javadoc must be present, not have any unknown tags and not missing any @param tags.

Restricts the NCSS score for methods, classes and files to 40, 1200 and 1600 respectively. The NCSS score is a measure of the number of statements within a scope.

Too high an NCSS score suggests that the method or class is doing too much and should be decomposed into smaller units.

Checks lambda body length.

Rationale: Similar to anonymous inner classes, if lambda body becomes very long it is hard to understand and to see the flow of the method where the lambda is defined. Therefore, long lambda body should usually be extracted to method.

Valid:

Runnable r3 = () -> { // ok, 10 lines
    System.out.println(2); // line 2 of lambda
    System.out.println(3);
    System.out.println(4);
    System.out.println(5);
    System.out.println(6);
    System.out.println(7);
    System.out.println(8);
    System.out.println(9);
}; // line 10

Invalid:

Runnable r = () -> { // violation, 11 lines
    System.out.println(2); // line 2 of lambda
    System.out.println(3);
    System.out.println(4);
    System.out.println(5);
    System.out.println(6);
    System.out.println(7);
    System.out.println(8);
    System.out.println(9);
    System.out.println(10);
}; // line 11

Runnable r2 = () -> // violation, 11 lines
  "someString".concat("1") // line 1 of lambda
              .concat("2")
              .concat("3")
              .concat("4")
              .concat("5")
              .concat("6")
              .concat("7")
              .concat("8")
              .concat("9")
              .concat("10")
              .concat("11"); // line 11

Checks the format of lambda parameter names.

Identifiers must match ^[a-z][a-zA-Z0-9]*$.

Checks that the left curly brace ('{') is placed at the end of the line. Does not check enums.

Valid:

class Foo {
}

Invalid:

class Bar
{

}

Limits the line length to 120 characters.

Doesn't check package or import lines.

Checks the format of local, final variable names, including catch parameters.

Identifiers must match ^[a-z][a-zA-Z0-9]*$.

Checks the format of local, non-final variable names.

Identifiers must match ^[a-z][a-zA-Z0-9]*$.

Checks that numeric literals are defined as constants. Being constants they then have a name that aids in making them non-magical.

The numbers -1, 0, 1 and 2 are not considered to be magical.

Valid:

static final int SECONDS_PER_DAY = 24 * 60 * 60;
static final Border STANDARD_BORDER = BorderFactory.createEmptyBorder(3, 3, 3, 3);

Invalid

String item = getItem(200);

Checks the format of non-static field names.

Identifiers must match ^[a-z][a-zA-Z0-9]*$.

Restricts the number of methods in a type to 30.

Restricts the number of lines in a method to 60. Include blank lines and single line comments. You should be able to see an entire method without needing to scroll.

Checks the format of method names.

Identifiers must match ^[a-z][a-zA-Z0-9]*$.

Checks that the padding between the method identifier and the left parenthesis is on the same line and doesn't have a space in-between.

Valid:

void getInstance();

Invalid:

void getInstance ();

void getValue
    ();

Restricts method generics parameters to be a single uppercase letter.

Valid:

List<A> getItems() {}

Invalid:

List<a> getItems() {}
List<BB> getItems() {}
List<C3> getItems() {}

Both the @Deprecated annotation and the Javadoc tag @deprecated must be used in pairs.

Valid:

/**
  * Foo.
  *
  * @deprecated
  */
@Deprecated
void foo() {}

Invalid:

/**
  * Foo.
  */
@Deprecated
void foo() {}

/**
  * Bar.
  *
  * @deprecated
  */
void bar() {}

Checks that switch statement has a default case.

Valid:

switch (foo) {
    case 1:
        //
        break;
    case 2:
        //
        break;
    default:
        throw new IllegalStateExcetion("Foo: " + foo);
}

Invalid:

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

Checks that the control variable in a for loop is not modified inside the loop.

Invalid:

for (int i = 0; i < 1; i++) {
    i++;
}

Check that modifiers are in the following order:

  • public
  • protected
  • private
  • abstract
  • static
  • final
  • transient
  • volatile
  • synchronized
  • native
  • strictfp

Type annotations are ignored.

Checks for multiple occurrences of the same string literal within a single file. Does not apply to empty strings ("").

Invalid:

String fooFoo = "foo" + "foo";

Checks that each variable is declared in its own statement and line.

Valid:

int a;
int b;

Invalid:

int a, b;

Checks that Exception classes are immutable. However, you can still call setStackTrace.

Classes checked are those whose name ends with the following. Or that the class they extend does.

  • Exception
  • Error
  • Throwable

Check that code blocks are surrounded by braces.

Valid:

if (obj.isValid()) {
    return true;
}

while (obj.isValid()) {
    return true;
}

do {
    this.notify();
} while (o != null);

for (int i = 0; ;) {
    this.notify();
}

Invalid:

if (obj.isValid()) return true;

while (obj.isValid()) return true;

do this.notify(); while (o != null);

for (int i = 0; ;) this.notify();

Checks that for loops are not nested more than 1 deep.

Valid:

for (int i = 0; i < 1; i++) { // depth 0
    for (int j = 0; j < 1; j++) { // depth 1
        //
    }
}

Invalid:

for (int i = 0; i < 1; i++) { // depth 0
    for (int j = 0; j < 1; j++) { // depth 1
        for (int k = 0; j < 1; k++) { // depth 2!
            //
        }
    }
}

Checks that if blocks are not nested more than 1 deep.

Valid:

if (isValid()) { // depth 0
    if (isExpected()) { // depth 1
        doIt();
    }
}

Invalid:

if (isValid()) { // depth 0
    if (isExpected()) { // depth 1
        if (isNecessary()) { // depth 2!
            doIt();
        }
    }
}

Checks that try blocks are not nested.

Valid:

try {
    doSomething();
    doSomeOtherThing();
} catch (SomeException se) {
    // handle it
} catch (OtherExceptions oe) {
    // handle it
}

Invalid:

try {
   doSomething();
   try {
       doSomeOtherThing();
   } catch (OtherExceptions oe) {
       // handle it
   }
} catch (SomeException se) {
   // handle it
}

Checks that files end with a line-feed character, (i.e. unix-style line ending).

This check cannot be suppressed.

Checks that the clone() method from Object has not been overridden. Use a copy constructor, or better yet, a static factory method.

See Effective Java, 2nd Edition by Josh Bloch: Item 11: Override clone judiciously.

Checks whether file contains code. Files which are considered to have no code:

  • File with no text
  • File with only single line comment(s)
  • File with only a multi line comment(s).

Invalid:

// single line comment // violation

Invalid:

/* // violation
 block comment
*/

Checks that the finalize() method from Object has not been overridden.

See Effective Java, 2nd Edition by Josh Bloch: Item 7: Avoid finalizers.

Prevents wrapping of package and import statements.

Checks that the Javadoc clauses @param, @return, @throws and @deprecated all have descriptions.

Valid:

/**
 * Foo.
 *
 * @returns the foo
 */

Invalid:

/**
 * Foo.
 *
 * @returns
 */

Checks that there is no whitespace after the array init ('{'), prefix increment ('++'), prefix decrement ('--'), bitwise complement ('~'), logical complement ('!'), array declaration ('[' in int[] a;) or array index operator ('[' in a[2]).

Valid:

int[] y = {1, 2};
++i;
--i;
int j = -1;
int k = +1;
int l = ~2;
boolean state = !isReady();
int b = o.getValue();
int[] a;
int d = a[2];

Invalid:

int[] y = { 1, 2 };
++ i;
-- i;
int j = - 1;
int k = + 1;
int l = ~ 2;
boolean state = ! isReady();
int b = o. getValue();
int[ ] a;
int d = a[ 2];

Checks that there is no whitespace before the comma operator (','), statement terminator (';'), postfix increment ('++') or postfix decrement ('--').

Valid:

int y = {1, 2};
doSomething();
i++;
i--;

Invalid:

int y = {1 , 2};
doSomething() ;
i ++;
i --;

Checks that there is no whitespace before the colon in a switch block. .

Valid:

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

Invalid:

switch(2) {
    case 2: // ok
        break;
    case 3, 4
             : break; // violation, whitespace before ':' is not allowed here
    case 4,
          5: break; // ok
    default
          : // violation, whitespace before ':' is not allowed here
        break;
}

Checks that the NPATH score (number of paths) through a method is no more than 5. This is similar to Cyclomatic Complexity.

Checks that there is only one statement per line.

Valid:

doSomething();
doSomethingElse();

Invalid:

doSomething(); doSomethingElse();

This check cannot be suppressed.

Checks that each source file contains only one top-level class, interface or enum.

Checks that when wrapping a line on an operator that the operator appears on the new line.

Valid:

int answer = getTheAnswerToLife() + getTheAnswerToTheUniverse()
    + getTheAnswerToEverything();

Invalid:

int answer = getTheAnswerToLife() + getTheAnswerToTheUniverse() +
    getTheAnswerToEverything();

This check cannot be suppressed.

Checks that the source filename matches the name of the top-level class. e.g. class Foo {} is in file Foo.java.

Checks that overload methods are grouped together in the source file.

Checks that package level annotations are in the package-info.java file.

This check cannot be suppressed.

Checks that the class has a package definition.

Checks the format of package names. Only lowercase letters, no initial numbers or any underscores.

Identifiers must match ^[a-z]+(\.[a-z][a-z0-9]+)*$.

Checks the format of method parameter names, including catch parameters.

Identifiers must match ^[a-z][a-zA-Z0-9]*$.

Restricts the number of parameters in a method or constructor to 7. Overridden methods are not checked as there may be no access to change the super method.

Checks that there are no spaces padding parentheses.

Valid:

doSomething();
doSomethingElse(5);

Invalid:

doSomething( );
doSomethingElse( 5);
doSomethingElse(5 );

Checks for the existence of forbidden java file names.

File names are forbidden if they match the pattern (.sync-conflict-| conflicted copy ).

N.B. only *.java files are checked.

This check is intended to detect Syncthing and Dropbox conflict files.

e.g.

DataClass (Bob's conflicted copy 2017-03-11).java
DataClass.sync-conflict-20170311-1648.java

Checks that references to instance fields where a parameter name overlaps are qualified by this..

Restricts methods to have at most 2 return statements in non-void methods, and at most 1 in void methods.

Valid:

int getNumber(int a) {
    if (a > 1) {
        return a;
    }
    return 0;
}

void getName(int a) {
    String name = "default";
    if (a > 1) {
        name = "Bob";
    }
    return name;
}

Invalid:

int getNumber(int a) {
    if (a > 1) {
        return a;
    }
    if (a < 2) {
        return a * a;
    }
    return 0;
}

void getName(int a) {
    if (a > 1) {
        return "Bob";
    }
    return "default";
}

Checks that the right curly brace ('}') is placed on the same line as the next part of a multi-block statement (e.g. try-catch-finally, if-then-else).

Valid:

try {
    //
} catch (Exception e) {
    //
} finally {
    //
}

if (a > 0) {
    //
} else {
    //
}

Invalid:

try {
    //
}
catch (Exception e) {
    //
}
finally {
    //
}

if (a > 0) {
    //
}
else {
    //
}

if (a > 0) {
    //
} a = 2;

public long getId() {return id;}

Checks the line wrapping around separators.

  • The comma separator (',') should be at the end of the line.
  • The dot separator ('.') should be on the new line.

Valid:

doSomething(alpha, beta,
    gamma);
doSomethingElse().stream()
                 .forEach(System.out::println);

Invalid:

doSomething(alpha, beta
    , gamma);
doSomethingElse().stream().
                  forEach(System.out::println);

Checks for overly complicated boolean expressions. Checks for code like b == true, b || true, !false, etc.

Valid:

if (b) {}
if (true) {}

Invalid:

if (b == true) {}
if (b || true) {}
if (!false) {}

Checks for overly complicated boolean return statements.

Valid:

return !valid();

Invalid:

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

Checks that non-whitespace characters on the same line are separated by no more than one whitespace.

Valid:

if (a < 0) {}
public long toNanos(long d) { return d; };

Invalid:

if  (a < 0) {}
public long toNanos(long d)  { return d;             };

Checks the format of static, non-final variable names.

Identifiers must match ^[a-z][a-zA-Z0-9]*$.

Checks that string literals are not used with == or !=.

Valid:

if ("something".equals(x)) {}

Invalid:

if (x == "something") {}

Prevents the use of @SuppressWarnings for the following checks:

Allows the use of the @SuppressWarnings annotation.

Used by Checkstyle to hold the checks to be suppressed from @SuppressWarnings(...) annotations.

Restricts non-private methods to only throws 4 distinct Exception types. Exceptions should be hierarchical to allow catching suitable root Exceptions.

See Effective Java, 2nd Edition, Chapter 9: Exceptions

Valid:

void doSomething() throws IllegalStateException, DowsingServiceException,
    BalancedBudgetException, ManagementInterferanceException {}

Invalid:

void doSomething() throws IllegalStateException,
    DowsingNotPermittedException, DowsingServiceNotReadyException,
    BalancedBudgetException, ManagementInterferanceException {}

Checks for remaining TODO and FIXME comments left in code. Their presence indicates that the program isn't finished yet.

Checks for comments at the end of lines.

Valid:

// comment on line by itself
    // comment after white space
if (a < 1) {
    //
} // comment on closing brace
int[] a = new int[2](
    1, 2
); // comment on closing parenthesis of statement

Invalid:

int a = 1; // comment in line with statement
if (a < 1) { // comment on line with if statement
    //
}
int[] a = new int[2](
    1, // first value - invalid comment
    2  // second value - also invalid comment
);

Checks that all messages*.properties files all have the same set of keys.

Checks that there are no spaces within the typecasting parentheses.

Valid:

String s = (String) list.get(2);

Invalid:

String s = (String ) list.get(2);
String s = ( String) list.get(2);
String s = ( String ) list.get(2);

This check cannot be suppressed.

Checks the format of class, interface, enum identifiers, including annotations.

Identifiers must match ^[A-Z][a-zA-Z0-9]*$.

Checks for public static void main() methods that may have been left over from testing. Allowed in classes whose names end in Main or Application.

Checks *.properties files for duplicate property keys.

Checks for the use of unnecessary parentheses.

Valid:

if (a < 1) {}

Invalid:

if ((a < 1)) {}

Checks if unnecessary semicolon is used after type declaration.

Valid:

class A {

   class Nested {

   }; // OK, nested type declarations are ignored

}

interface B {

}

enum C {

}

@interface D {

}

Invalid:

class A {

   class Nested {

   }; // OK, nested type declarations are ignored

}; // violation

interface B {

}; // violation

enum C {

}; // violation

@interface D {

}; // violation

Checks for unused imports. Does not inspect wildcard imports, which should be blocked by AvoidStarImport anyway.

Imports are unused if:

  • They are not referenced in the file.
  • It duplicates another import.
  • It import from the java.lang package.
  • It imports a class from the same package.
  • It is only references from the Javadoc.

Checks that long numeric literal values are marked by an upper-case ell ('L'). The lower-case ell ('l') can be mistaken for the numeral one ('1').

Valid:

long id = 12345L;

Invalid:

long id = 12345l;

Checks that a variable declaration and its first usage are not more than 3 lines. Blocks of initialisation methods don't count toward this total.

See the official Checkstyle documentation for examples.

This check cannot be suppressed.

Checks the visibility of class members to help enforce encapsulation. Only static final fields, immutable (see list below) fields or field with special annotation (see list below), may be public.

The following are considered immutable when final, and can be public:

  • java.lang.String
  • java.lang.Integer
  • java.lang.Byte
  • java.lang.Character
  • java.lang.Short
  • java.lang.Boolean
  • java.lang.Long
  • java.lang.Double
  • java.lang.Float
  • java.lang.StackTraceElement
  • java.math.BigInteger
  • java.math.BigDecimal
  • java.io.File
  • java.util.Locale
  • java.util.UUID
  • java.net.URL
  • java.net.URI
  • java.net.Inet4Address
  • java.net.Inet6Address
  • java.net.InetSocketAddress

Fields with the following annotations may be public:

  • org.junit.Rule
  • org.junit.ClassRule
  • com.google.common.annotations.VisibleForTesting

Valid:

class Foo {

    public final Long id;

    public final String name;

    private String description;

    @VisibleForTesting
    public State state;

    Foo(final Long id, final String name) {
        this.id = id;
        this.name = name;
    }
}

Invalid:

class Foo {

    public Long id;

    public String name;

    private String description;

    public State state;

    Foo(final Long id, final String name) {
        this.id = id;
        this.name = name;
    }
}

Checks that commas (','), statement terminators (';') and typecasts are all followed by a space.

Valid:

doSomething(1, 2, 3);
if (a > 1) { return true; }
String name = (String) list.get(9);

Inalid:

doSomething(1,2,3);
if (a > 1) { return true;}
String name = (String)list.get(9);

Checks that tokens are surrounded by whitespace.

Sevntu

Disabled Checks

These checks are not enabled. Notes are included for each explaining why.

Checkstyle

Prevents some more meaningful abstract class names

Couldn't get my IDE's (IntelliJ) code style to match.

Ref: Clean Code, Robert C. Martin, J1: Avoid Long Import Lists by Using Wildcards

Ref: Clean Code, Robert C. Martin, J2: Don't Inherit Constants Recommends using a static import to access constants from another class over inheriting them.

Doesn't recognise Lombok's val as being final.

Shouldn't need to list in every file, simply listing in project root should be enough.

Not really suitable for a template ruleset as it requires an explicit list of classes to apply to.

Generic rule; doesn't embody a 'quality' check.

Generic rule; doesn't embody a 'quality' check.

Generic rule; doesn't embody a 'quality' check.

Couldn't get my IDE's (IntelliJ) code style to match.

Makes interfaces overly verbose.

Only exceptional cases should need to be documented.

Couldn't get my IDE's (IntelliJ) code style to match.

Member variables should usually be named such that it is clear what they are. Comments for clarification should be the exception.

Would not see constructors created using Lombok's @NoArgsConstructor.

The javadoc compiler automatically inherits the javadoc from the overridden method, it doesn't need to be told to do so.

Already covered by the OneTopLevelClass check.

FinalParameters already protects against assigning values to parameters.

UnusedImports performs all the same checks and more.

conflicts with InterfaceMemberImpliedModifier which is now prefered given changes to interfaces in Java 9

Generic rule; doesn't embody a 'quality' check.

Generic rule; doesn't embody a 'quality' check.

Generic rule; doesn't embody a 'quality' check.

Generic rule; doesn't embody a 'quality' check.

Generic rule; doesn't embody a 'quality' check.

Generic rule; doesn't embody a 'quality' check.

I don't use single line javadoc blocks.

Generic rule; doesn't embody a 'quality' check.

Overridding the clone() method is not allowed by the NoClone check.

NoFinalizer prevents use of finalize().

Generic rule; doesn't embody a 'quality' check.

Sevntu

As the sevntu check are considered experimental not all those that are not enabled are listed here. Only where they are disabled due to a conflict with my 'style' or there is another irreconcilable difference that prevents them from being enabled, will they be documented to prevent repeated investigations.

Should already be covered by SimplifyBooleanExpression.

Checks that condition expressions don't become less readable by attempting to use a constant on the left-hand-side of a comparison.

Valid:

if (a == 12) {}

Invalid:

if (12 == a) {}

Prevent the use of default serialization methods on inner classes. If an inner class needs to implement the Serializable interface, then it must implement both writeObject() and readObject() methods.

Ensures that an exception is re-thrown properly and is not swallowed by a catch block.

Valid:

try {
    doSomething();
} catch (MyException e) {
    throw new MyOtherException(e);
}

Invalid:

try {
    doSomething();
} catch (MyException e) {
    throw new MyOtherException();
}

Generic rule; doesn't embody a 'quality' check.

Prevents the use of boolean operators that don't allow short-circuiting the expression. (e.g. '|', '&', '|=' and '&=')

Valid:

if ((a < b) || (b > getExpensiveValue())) {}

Invalid:

if ((a < b) | (b > getExpensiveValue())) {}

Should already be covered by AvoidHidingCauseException.

Appears to be broken as of 1.21.0.

Checks that the expression with the if condition in an if-then-else statement is not negated.

Valid:

if (isValid()) {
    handleValidCondition();
} else {
    handleInvalidCondition();
}

Invalid:

if (!isValid()) {
    handleInvalidCondition();
} else {
    handleValidCondition();
}

Exception class constructors must accept parameters for message and/or cause. This check is applied to classes whose name ends with Exception.

The DeclarationOrder check already imposes an order for class elements.

Checks that the diamond operator is used where possible.

Valid:

Map<Long, String> idTable = new HashMap<>();

Invalid:

Map<Long, String> idTable = new HashMap<Long, String>();

Checks that when an exception is caught, that if it is logged then it is not also re-thrown. Log or throw; one or the other or neither, but not both.

Accepts java.util.logging.Logger and org.slf4j.Logger.

This Check looks for useless empty public constructors. Class constructor is considered useless by this Check if and only if class has exactly one ctor, which is public, empty(one that has no statements) and default.

Valid:

class ValidPrivateCtor {
    private ValidPrivateCtor() {
    }
}

class ValidOverloadedCtor {
    public ValidOverloadedCtor() {
    }
    public ValidOverloadedCtor(int i) {
    }
}

Invalid:

class Invalid {
     public Invalid() {
     }
}

Checks that Enum Values match the pattern: ^[A-Z][A-Z0-9]*(_[A-Z0-9]+)*$

Valid:

enum Valid {

    ALPHA, BETA, GAMMA_RAY;
}

Invalid:

enum InvalidConstants {

    alpha, Beta;
}

Checks that the finalize() implementation doesn't ignore the base class implementation, and doesn't only call the base class implementation.

Valid:

class Valid {
    protected void finalize() {
        try {
            doSomething();
        } finally {
            super.finalize();
        }
    }
}

Invalid:

class InvalidNoEffect1 {
    protected void finalize() {
    }
}
class InvalidNoEffect2 {
    protected void finalize() {
        doSomething();
    }
}
class InvalidUseless {
    protected void finalize() {
        super.finalize();
    }
}
class InvalidPublic {
    public void finalize() {
        try {
            doSomething();
        } finally {
            super.finalize();
        }
    }
}

Generic rule; doesn't embody a 'quality' check.

Prevents the use of /* C-style */ comments inside methods.

Valid:

void doSomething() {
    // a comment
}

Invalid:

void doSomething() {
    /* invalid */
}

Generic rule; doesn't embody a 'quality' check.

Generic rule; doesn't embody a 'quality' check.

Prevent the use of a return statement in the finally block.

Invalid:

try {
    doSomething();
{ catch (IOException e) {
    // log error
} finally (
    return true; // invalid
}

IllegalThrows performs a similar check.

Prevents declaring a method from returning a wildcard type as its return value.

Valid:

<E> List<E> getList() {}

Invalid:

<E> List<? extends E> getList() {}

Prevent the placement of variables or fields after methods in an expression.

Valid:

if (property && getProperty()) {}

Invalid:

if (getProperty() && property) {}

Checks for unoptimised iterations over Maps. Check use of map.values(), map.keySet() and map.entrySet() against the use of the iterator produced to verify if another could be better.

Checks if a variable is declared outside an if block that is only used within that block.

Valid:

if (condition) {
    String variable = input.substring(1);
    return method(variable);
}
return "";

Invalid:

String variable = input.substring(1);
if (condition) {
    return method(variable);
}
return "";

Checks the names of JUnit test classes. Classes checked are those that have at least one method annotated with Test or org.junit.Test.

Test class names must match: .+Test\\d*|.+Tests\\d*|Test.+|Tests.+|.+IT|.+ITs|.+TestCase\\d*|.+TestCases\\d*

Checks that switch statements are not nested within one another.

Valid:

void doSomething(int a, int b) {

    switch(a) {
        case 1:
            doMore(b);
            break;
        case 2:
            // ..
        }
    }
}

void doMore(int b) {

    switch(b) {
        case 1:
            //
        case 2:
            //
    }
}

Invalid:

void doSomething(int a, int b) {

    switch(a) {
        case 1:
            switch(b) {
                case 1:
                    //
                case 2:
                    //
            }
            break;
        case 2:
            // ..
        }
    }
}

Prevents a main method from existing in an abstract class.

Checks that numeric literals use underscores ('_') if over a certain length.

  • Decimals

    • 7 or more digits must use the underscore
    • No more than 3 digits between underscores
  • Hex

    • 5 or more digits must use the underscore
    • No more than 4 digits between underscores
  • Binary

    • 9 or more digits must use the underscore
    • No more than 8 digits between underscores

Prevents calls to overridable methods from constuctors including other methods that perform the same functions. (i.e. Cloneable.clone() and Serializable.readObject())

Invalid:

abstract class Base {
    Base() {
        overrideMe();
    }
}
class Child extends Base {
    final int x;
    Child(int x) {
        this.x = x;
    }
    void overrideMe() {
        System.out.println(x);
    }
}
new Child(42); // prints "0"

Checks that a type is not exposed outside its declared scope.

Invalid:

public class OuterClass {
    public InnerClass inner = new InnerClass();
    public SiblingClass sibling = new SiblingClass();
    public InnerClass getValue() { return new InnerClass(); }
    public SiblingClass getSibling() { return new SiblingClass(); }
    private class InnerClass {}
}
class SiblingClass {}

Checks for redundant return statements.

Invalid:

HelloWorld() {
    doStuff();
    return;
}
void doStuff() {
    doMoreStuff();
    return;
}

Generic rule; doesn't embody a 'quality' check.

Ternary statements shouldn't have Boolean values as results.

Valid:

Boolean set = isSet();
Boolean notReady = !isReady();

Invalid:

Boolean set = isSet() ? True : False;
Boolean notReady = isReady() ? False : True;

The Boolean type is meant to only represent a binary state: TRUE or FALSE. It is not a ternary value: TRUE, FALSE, null.

Invalid:

Boolean isEnabled() {
    if (level > 0) {
        return True;
    }
    if (level < 0) {
        return False;
    }
    return null;
}

allow use of non-bean property-like naming

Checks that there is at most one continue or break statement within a looping block (e.g. for, while, ...)

Can't handle private methods called by reflection, which may cause issues with Spring and other DI frameworks.

Checks that there is at most one ternary statments (?:) within an expression.

Invalid:

String x = value != null ? "A" : "B" + value == null ? "C" : "D"

Checks that all the values of an enum follow the same naming pattern.

Valid:

public enum EnumOne {
    FirstElement, SecondElement, ThirdElement;
}

public enum EnumTwo {
    FIRST_ELEMENT, SECOND_ELEMENT, THIRD_ELEMENT;
}

Invalid:

public enum EnumThree {
    FirstElement, SECOND_ELEMENT, ThirdElement;
}

Checks for catch blocks that are useless. i.e. that catch all exceptions and then just rethrow them.

Invalid:

try {
    doSomething();
} catch (Exception e) {
    throw e;
}

Checks for useless calls to the super() method in constructors.

Invalid:

class Dummy {
    Dummy() {
        super();
    }
}
class Derived extends Base {
    Derived() {
        super();
    }
}

This checks enforces whitespace before array initializer.

Valid:

int[] ints = new int[] {
    0, 1, 2, 3
};

int[] tab = new int[]
                {0, 1, 2, 3};

Invalid:

int[] ints = new int[]{0, 1, 2, 3};