We use Checkstyle to enforce a consistent coding style. This document provides a guide for writing Java codes that adhere to the Checkstyle rules.
What is Checkstyle? Just like its name, Checkstyle is a tool that checks your Java code for adherence to a coding standard. It is highly configurable and can be made to support almost any coding standard. It is widely used in the industry and is a must-have tool for any Java developer.
Checks whether files end with a new line.
Correct:
public class Example1 { // ⤶
// ⤶
} // ⤶ // ok, file ends with a new line.
Incorrect:
public class Example2 { // ⤶
// ⤶
} // error, file does not end with a new line.
Checks the number of lines in a file. The default maximum is 2000 lines.
Checks the length of each line in the file. The default maximum is 80 characters. Here we set it to 120 characters.
Correct:
public class Example3 {
public static void main(String[] args) {
System.out.println("Hello, World!");
}
}
Incorrect:
public class Example4 {
public static void main(String[] args) {
// voilation below 'Line is longer than 80 characters (found 95).'
System.out.println("THIS IS REALLY LONG LONG LONG LONG LONG AND EXTREMELY LONG LINE");
}
}
Checks for tab characters in the file. Tabs are not allowed.
Correct:
class Example1 {
public static void main(String[] args) {
System.out.println("Hello, World!");
}
}
Incorrect:
class Example2 {
public static void main(String[] args) {
// voilation below 'File contains tab characters.'
System.out.println("Hello, World!");
}
}
Here we have custom rule to check for trailing spaces in the file.
Correct:
class Example1 {
public static void main(String[] args) {
System.out.println("Hello, World!");
}
}
Incorrect:
class Example2 {
public static void main(String[] args) {
// voilation below 'Line has trailing spaces.'
System.out.println("Statement with trailing spaces!");
// trailing spaces in the above line ^^^^
}
}
Checks the names of constants. The default pattern is ^[A-Z][A-Z0-9]*(_[A-Z0-9]+)*$
.
Correct:
public class Example1 {
private static final int MAX_VALUE = 100;
}
Incorrect:
public class Example2 {
private static final int max_value = 100; // voilation 'Must match pattern '^[A-Z][A-Z0-9]*(_[A-Z0-9]+)*$'.'
}
Checks the names of local final variables. The default pattern is ^[a-z][a-zA-Z0-9]*$
.
Correct:
public class Example1 {
public static void main(String[] args) {
final int max = 100;
}
}
Incorrect:
public class Example2 {
public static void main(String[] args) {
final int Max = 100; // voilation 'Must match pattern '^[a-z][a-zA-Z0-9]*$'.'
}
}
Checks the names of local variables. The default pattern is ^[a-z][a-zA-Z0-9]*$
.
Correct:
public class Example1 {
public static void main(String[] args) {
int max = 100;
}
}
Incorrect:
public class Example2 {
public static void main(String[] args) {
int Max = 100; // voilation 'Must match pattern '^[a-z][a-zA-Z0-9]*$'.'
}
}
Checks the names of member variables. The default pattern is ^[a-z][a-zA-Z0-9]*$
.
Correct:
public class Example1 {
private int max;
}
Incorrect:
public class Example2 {
private int Max; // voilation 'Must match pattern '^[a-z][a-zA-Z0-9]*$'.'
}
Checks the names of methods. The default pattern is ^[a-z][a-zA-Z0-9]*$
.
Correct:
public class Example1 {
public void print() {
System.out.println("Hello, World!");
}
}
Incorrect:
public class Example2 {
public void Print() { // voilation 'Must match pattern '^[a-z][a-zA-Z0-9]*$'.'
System.out.println("Hello, World!");
}
}
Checks the names of packages. The default pattern is ^[a-z]+(\.[a-z][a-z0-9]*)*$
.
Correct:
package com.example;
Incorrect:
package com.Example; // voilation 'Must match pattern '^[a-z]+(\.[a-z][a-z0-9]*)*$'.'
Checks the names of parameters. The default pattern is ^[a-z][a-zA-Z0-9]*$
.
Correct:
public class Example1 {
public void print(String message) {
System.out.println(message);
}
}
Incorrect:
public class Example2 {
public void print(String Message) { // voilation 'Must match pattern '^[a-z][a-zA-Z0-9]*$'.'
System.out.println(Message);
}
}
Checks the names of static variables. The default pattern is ^[a-z][a-zA-Z0-9]*$
.
Correct:
public class Example1 {
private static int max;
}
Incorrect:
public class Example2 {
private static int Max; // voilation 'Must match pattern '^[a-z][a-zA-Z0-9]*$'.'
}
Checks the names of types. The default pattern is ^[A-Z][a-zA-Z0-9]*$
.
Correct:
public class Example1 {
private int max;
}
Incorrect:
public class example2 { // voilation 'Must match pattern '^[A-Z][a-zA-Z0-9]*$'.'
private int max;
}
Checks for star imports. Star imports are not allowed, except for java.lang
and java.util
.
Correct:
import java.util.List;
Incorrect:
import java.util.*; // voilation 'Avoid using star imports.'
Checks for illegal imports. The default illegal package is sun.*
.
Correct:
import java.util.List;
Incorrect:
import sun.misc.BASE64Encoder; // voilation 'Illegal import of sun class: sun.misc.BASE64Encoder.'
Checks for redundant imports.
Correct:
import java.util.List;
Incorrect:
import java.util.List; // voilation 'Redundant import from the same package.'
Checks for unused imports.
Correct:
import java.util.List;
Incorrect:
import java.util.List; // voilation 'Unused import.'
Checks the number of lines in a method. The default maximum is 150 lines.
Checks the number of parameters in a method. The default maximum is 7 parameters.
Checks for padding around the :
in an enhanced for loop.
Correct:
public class Example1 {
public static void main(String[] args) {
for (String arg : args) {
System.out.println(arg);
}
}
}
Incorrect:
public class Example2 {
public static void main(String[] args) {
for (String arg: args) { // voilation 'Whitespace is not allowed after ":".'
System.out.println(arg);
}
}
}
Checks for whitespace around generic types.
Correct:
public class Example1 {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
}
}
Incorrect:
public class Example2 {
public static void main(String[] args) {
List <String> list = new ArrayList<>(); // voilation 'Whitespace is not allowed before "<".'
}
}
Checks for padding around method parameters.
Correct:
public class Example1 {
public void print(String message) {
System.out.println(message);
}
}
Incorrect:
public class Example2 {
public void print( String message ) { // voilation 'Whitespace is not allowed before ")"'
System.out.println(message);
}
}
Checks for wrapping of operators.
Correct:
public class Example1 {
public static void main(String[] args) {
int sum = 1 + 2;
}
}
Incorrect:
public class Example2 {
public static void main(String[] args) {
int sum = 1
+ 2; // voilation 'Operator + should be on the previous line.'
}
}
Checks for padding around parentheses.
Correct:
public class Example1 {
public static void main(String[] args) {
int sum = (1 + 2);
}
}
Incorrect:
public class Example2 {
public static void main(String[] args) {
int sum = ( 1 + 2 ); // voilation 'Whitespace is not allowed after "(".'
}
}
Checks for padding around typecasts.
Correct:
public class Example1 {
public static void main(String[] args) {
int sum = (int) 3.14;
}
}
Incorrect:
public class Example2 {
public static void main(String[] args) {
int sum = ( int ) 3.14; // voilation 'Whitespace is not allowed after "(".'
}
}
Checks for whitespace after certain keywords.
Correct:
public class Example1 {
public static void main(String[] args) {
if (true) {
System.out.println("Hello, World!");
}
}
}
Incorrect:
public class Example2 {
public static void main(String[] args) {
if(true) { // voilation 'Whitespace is required after "if".'
System.out.println("Hello, World!");
}
}
}
Checks for whitespace around certain operators.
Correct:
public class Example1 {
public static void main(String[] args) {
int sum = 1 + 2;
}
}
Incorrect:
public class Example2 {
public static void main(String[] args) {
int sum = 1+2; // voilation 'Whitespace is required around "+"'
}
}
Checks the order of modifiers.
The correct order is:
public
protected
private
abstract
default
static
sealed
non-sealed
final
transient
volatile
synchronized
native
strictfp
Correct:
public final class Example1 {
public static final int MAX_VALUE = 100;
private static final int MIN_VALUE = 0;
protected static final int DEFAULT_VALUE = 50;
}
Incorrect:
public final class Example2 {
final public static int MAX_VALUE = 100; // voilation 'Modifier 'final' must appear before 'public'.'
static private final int MIN_VALUE = 0; // voilation 'Modifier 'static' must appear before 'private'.'
protected final static int DEFAULT_VALUE = 50; // voilation 'Modifier 'protected' must appear before 'static'.'
}
Checks for redundant modifiers.
Correct:
public final class Example1 {
public static final int MAX_VALUE = 100;
}
Incorrect:
public final static class Example2 { // voilation 'Redundant 'static' modifier.'
public static final int MAX_VALUE = 100;
}
Checks for nested blocks.
Correct:
public class Example1 {
public static void main(String[] args) {
if (true) {
System.out.println("Hello, World!");
}
}
}
Incorrect:
public class Example2 {
public static void main(String[] args) {
if (true) { // voilation 'Nested blocks of code detected.'
if (true) {
System.out.println("Hello, World!");
}
}
}
}
Checks for empty blocks.
Correct:
public class Example1 {
public static void main(String[] args) {
if (true) {
System.out.println("Hello, World!");
}
}
}
Incorrect:
public class Example2 {
public static void main(String[] args) {
if (true) { // voilation 'Empty block.'
}
}
}
Checks for the placement of the left curly brace.
Correct:
public class Example1 {
public static void main(String[] args) {
if (true) {
System.out.println("Hello, World!");
}
}
}
Incorrect:
public class Example2
{
public static void main(String[] args) { // voilation 'Left curly brace is not preceded by whitespace.'
System.out.println("Hello, World!");
}
}
Checks for the use of braces in certain statements.
Correct:
public class Example1 {
public static void main(String[] args) {
if (true) {
System.out.println("Hello, World!");
}
}
}
Incorrect:
public class Example2 {
public static void main(String[] args) {
if (true) // voilation 'Statement without braces.'
System.out.println("Hello, World!");
}
}
Checks for the placement of the right curly brace.
Correct:
public class Example1 {
public static void main(String[] args) {
if (true) {
System.out.println("Hello, World!");
}
}
}
Incorrect:
public class Example2 {
public static void main(String[] args) {
if (true) {
System.out.println("Hello, World!");
} // voilation 'Right curly brace is not followed by whitespace.'
}
}
Checks for empty catch blocks.
Correct:
public class Example1 {
public static void main(String[] args) {
try {
throw new Exception();
} catch (Exception e) {
System.out.println("Caught an exception!");
}
}
}
Incorrect:
public class Example2 {
public static void main(String[] args) {
try {
throw new Exception();
} catch (Exception e) { // voilation 'Empty catch block.'
}
}
}
Checks for empty statements.
Correct:
public class Example1 {
public static void main(String[] args) {
System.out.println("Hello, World!");
}
}
Incorrect:
public class Example2 {
public static void main(String[] args) {
; // voilation 'Empty statement.'
System.out.println("Hello, World!");
}
}
Checks for the presence of equals
and hashCode
methods in classes that override equals
.
Correct:
public class Example1 {
private int value;
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null || getClass() != obj.getClass()) {
return false;
}
Example1 example = (Example1) obj;
return value == example.value;
}
@Override
public int hashCode() {
return Objects.hash(value);
}
}
Incorrect:
public class Example2 {
private int value;
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null || getClass() != obj.getClass()) {
return false;
}
Example2 example = (Example2) obj;
return value == example.value;
}
// voilation 'Class does not override equals() in superclass.'
}
HiddenField
Checks for hidden fields.
Correct:
public class Example1 {
private int value;
public void setValue(int value) {
this.value = value;
}
}
Incorrect:
public class Example2 {
private int value;
public void setValue(int value) {
value = value; // voilation 'Hidden field.'
}
}
Checks for illegal instantiations.
Correct:
public class Example1 {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
}
}
Incorrect:
public class Example2 {
public static void main(String[] args) {
List<String> list = new ArrayList<String>(); // voilation 'Illegal instantiation.'
}
}
Checks for inner assignments.
Correct:
public class Example1 {
public static void main(String[] args) {
int a = 1;
int b = 2;
int c = a + b;
}
}
Incorrect:
public class Example2 {
public static void main(String[] args) {
int a = 1;
int b = 2;
int c = a = b; // voilation 'Assignment in operand.'
}
}
Checks for missing default
cases in switch
statements.
Correct:
public class Example1 {
public static void main(String[] args) {
int value = 1;
switch (value) {
case 1:
System.out.println("One");
break;
case 2:
System.out.println("Two");
break;
default:
System.out.println("Other");
}
}
}
Incorrect:
public class Example2 {
public static void main(String[] args) {
int value = 1;
switch (value) {
case 1:
System.out.println("One");
break;
case 2:
System.out.println("Two");
break;
// voilation 'Switch statement without a default case.'
}
}
}
Checks for multiple variable declarations in a single statement.
Correct:
public class Example1 {
public static void main(String[] args) {
int a = 1;
int b = 2;
int c = 3;
}
}
Incorrect:
public class Example2 {
public static void main(String[] args) {
int a = 1, b = 2, c = 3; // voilation 'Multiple variable declarations.'
}
}
Checks for simplified boolean expressions.
Correct:
public class Example1 {
public static void main(String[] args) {
boolean a = true;
boolean b = false;
boolean c = a && b;
}
}
Incorrect:
public class Example2 {
public static void main(String[] args) {
boolean a = true;
boolean b = false;
boolean c = a == true && b == false; // voilation 'Simplify boolean expression.'
}
}
Checks for simplified boolean return statements.
Correct:
public class Example1 {
public static boolean isTrue() {
return true;
}
}
Incorrect:
public class Example2 {
public static boolean isTrue() {
if (true) {
return true;
} else {
return false;
}
}
}
Checks for classes that are not designed for extension.
Correct:
public final class Example1 {
public void print() {
System.out.println("Hello, World!");
}
}
Incorrect:
public class Example2 { // voilation 'Class is not designed for extension.'
public void print() {
System.out.println("Hello, World!");
}
}
Checks for classes that are not final.
Correct:
public final class Example1 {
public void print() {
System.out.println("Hello, World!");
}
}
Incorrect:
public class Example2 { // voilation 'Class is not final.'
public void print() {
System.out.println("Hello, World!");
}
}
Checks for interfaces that are not types.
Correct:
public interface Example1 {
void print();
}
Incorrect:
public class Example2 { // voilation 'Interface is not a type.'
void print();
}
Checks for the use of visibility modifiers.
Correct:
public class Example1 {
public void print() {
System.out.println("Hello, World!");
}
}
Incorrect:
public class Example2 {
void print() { // voilation 'Missing visibility modifier.'
System.out.println("Hello, World!");
}
}
Checks for multiple top-level classes in a single file.
Correct:
public class Example1 {
public void print() {
System.out.println("Hello, World!");
}
}
Incorrect:
public class Example2 {
public void print() {
System.out.println("Hello, World!");
}
}
public class Example3 { // voilation 'More than one top-level class in the file.'
public void print() {
System.out.println("Hello, World!");
}
}
Checks for the style of array types.
Correct:
public class Example1 {
private int[] array;
}
Incorrect:
public class Example2 {
private int array[]; // voilation 'Array type style.'
}
Checks for final parameters.
Correct:
public class Example1 {
public void print(final String message) {
System.out.println(message);
}
}
Incorrect:
public class Example2 {
public void print(String message) { // voilation 'Parameter is not final.'
System.out.println(message);
}
}
Checks for TODO
comments.
Correct:
public class Example1 {
public void print() {
System.out.println("Hello, World!");
}
}
Incorrect:
public class Example2 {
public void print() {
// TODO: Implement this method // voilation 'TODO comment found.'
}
}
Checks for the use of upper-case L
in long literals.
Correct:
public class Example1 {
private long value = 100L;
}
Incorrect:
public class Example2 {
private long value = 100l; // voilation 'Use upper case 'L' for long literals.'
}
Checks for the indentation of comments.
Correct:
public class Example1 {
public void print() {
// This is a comment
}
}
Incorrect:
public class Example2 {
public void print() {
// This is a comment // voilation 'Comment has incorrect indentation level 3, expected is 1.'
}
}
Checks for suppression comments. Use // CSOFF: <checkname>
to suppress a check. Use // CSON: <checkname>
to re-enable a check.
Correct:
public class Example1 {
public void print() {
// CSOFF: TodoComment
// TODO: Implement this method
}
}
Incorrect:
public class Example2 {
public void print() {
// TODO: Implement this method // voilation 'TODO comment found.'
}
}
These rules are just a subset of the rules that Checkstyle provides. There is no strict rule for this project, but it is recommended to follow these rules to maintain a consistent coding style.