Indentation
Since Checkstyle 3.1
Description
The idea behind this is that while pretty printers are sometimes convenient for bulk reformats of legacy code, they often either aren't configurable enough or just can't anticipate how format should be done. Sometimes this is personal preference, other times it is practical experience. In any case, this check should just ensure that a minimal set of indentation rules is followed.
Basic offset indentation is used for indentation inside code blocks. For any lines that span more than 1, line wrapping indentation is used for those lines after the first. Brace adjustment, case, and throws indentations are all used only if those specific identifiers start the line. If, for example, a brace is used in the middle of the line, its indentation will not take effect. All indentations have an accumulative/recursive effect when they are triggered. If during a line wrapping, another code block is found and it doesn't end on that same line, then the subsequent lines afterwards, in that new code block, are increased on top of the line wrap and any indentations above it.
Example:
if ((condition1 && condition2)
|| (condition3 && condition4) // line wrap with bigger indentation
||!(condition5 && condition6)) { // line wrap with bigger indentation
field.doSomething() // basic offset
.doSomething() // line wrap
.doSomething( c -> { // line wrap
return c.doSome(); // basic offset
});
}
Properties
| name | description | type | default value | since |
|---|---|---|---|---|
| arrayInitIndent | Specify how far an array initialization should be indented when on next line. | int | 4 |
5.8 |
| basicOffset | Specify how far new indentation level should be indented when on the next line. | int | 4 |
3.1 |
| braceAdjustment | Specify how far a braces should be indented when on the next line. | int | 0 |
3.1 |
| caseIndent | Specify how far a case label should be indented when on next line. | int | 4 |
3.1 |
| forceStrictCondition | Force strict indent level in line wrapping case. If value is true, line wrap indent have to be same as lineWrappingIndentation parameter. If value is false, line wrap indent could be bigger on any value user would like. | boolean | false |
6.3 |
| lineWrappingIndentation | Specify how far continuation line should be indented when line-wrapping is present. | int | 4 |
5.9 |
| throwsIndent | Specify how far a throws clause should be indented when on next line. | int | 4 |
5.7 |
Examples
To configure the default check:
<module name="Checker">
<module name="TreeWalker">
<module name="Indentation"/>
</module>
</module>
Example of Compliant code for default configuration (in comment name of property that controls indentations):
class Example1 {
int a; // ok, basicOffset = 4
boolean x, y;
String field = "example";
int[] values = {
1, 2, 3 // ok, arrayInitIndent = 4
};
int[] values2 = {
10 // violation, 'level 2, expected level should be 8'
};
void method2()
throws Exception {
switch (a) {
case 1: // ok, caseIndent = 4
break;
case 2:
break;
}
}
void method3(int a,
int b) {
if (x
&& y) {
method3(a, b);
}
}
void handleValue(String aFooString,
int aFooInt) {
boolean cond1,cond2,cond3,cond4,cond5,cond6;
cond1=cond2=cond3=cond4=cond5=cond6=false;
if (cond1
|| cond2) {
field = field.toUpperCase()
.concat(" TASK");
}
}
void methodBrace()
{
}
}
To configure the check to enforce the indentation style recommended by Oracle:
<module name="Checker">
<module name="TreeWalker">
<module name="Indentation">
<property name="caseIndent" value="0"/>
</module>
</module>
</module>
Example of Compliant code for default configuration (in comment name of property that controls indentation):
class Example2 {
int a;
boolean x, y;
String field = "example";
int[] values = {
1, 2, 3
};
int[] values2 = {
10 // violation, 'level 2, expected level should be 8'
};
void method2()
throws Exception {
switch (a) {
case 1: // violation, 'level 12, expected level should be 8'
break; // violation, 'level 16, expected level should be 12'
case 2: // violation, 'level 12, expected level should be 8'
break; // violation, 'level 16, expected level should be 12'
}
}
void method3(int a,
int b) {
if (x
&& y) {
method3(a, b);
}
}
void handleValue(String aFooString,
int aFooInt) {
boolean cond1,cond2,cond3,cond4,cond5,cond6;
cond1=cond2=cond3=cond4=cond5=cond6=false;
if (cond1
|| cond2) {
field = field.toUpperCase()
.concat(" TASK");
}
}
void methodBrace()
{
}
}
To configure the Check to enforce strict condition in line-wrapping validation.
<module name="Checker">
<module name="TreeWalker">
<module name="Indentation">
<property name="forceStrictCondition" value="true"/>
</module>
</module>
</module>
Such config doesn't allow next cases even code is aligned further to the right for better reading:
class Example3 {
int a;
boolean x, y;
String field = "example";
int[] values = {
1, 2, 3
};
int[] values2 = {
10 // violation, 'level 2, expected level should be 8'
};
void method2()
throws Exception {
switch (a) {
case 1: // ok, caseIndent = 4
break;
case 2:
break;
}
}
void method3(int a,
int b) { // violation, 'level 17, expected level should be 8'
if (x
&& y) { // violation, 'level 16, expected level should be 12'
method3(a, b);
}
}
// violation 2 lines below 'level 21, expected level should be 8'
void handleValue(String aFooString,
int aFooInt) {
boolean cond1,cond2,cond3,cond4,cond5,cond6;
cond1=cond2=cond3=cond4=cond5=cond6=false;
if (cond1
|| cond2) { // violation, 'level 16, expected level should be 12'
field = field.toUpperCase()
.concat(" TASK");
}
}
void methodBrace()
{
}
}
But if forceStrictCondition = false, this code is valid:
class Example4 {
int a; // violation, 'level 6, expected level should be 4'
void method() {
int b = 0; // ok
int c = 1; // violation, 'level 10, expected level should be 8'
}
}
To configure the check with custom basicOffset (2 spaces instead of default 4):
<module name="Checker">
<module name="TreeWalker">
<module name="Indentation">
<property name="basicOffset" value="2"/>
</module>
</module>
</module>
Example of code with basicOffset set to 2:
class Example5 {
int a; // violation, 'level 4, expected level should be 2'
boolean x, y; // violation, 'level 4, expected level should be 2'
String field = "example"; // violation, 'level 4, expected level should be 2'
int[] values = { // violation, 'level 4, expected level should be 2'
1, 2, 3
};
int[] values2 = { // violation, 'level 4, expected level should be 2'
10 // violation,'level 2, expected level should be one of the following: 8, 23, 24'
};
void method2() // violation, 'level 4, expected level should be 2'
throws Exception {
switch (a) { // violation, 'level 8, expected level should be 4'
case 1: // violation, 'level 12, expected level should be 8'
break; // violation, 'level 16, expected level should be 10'
case 2: // violation, 'level 12, expected level should be 8'
break; // violation, 'level 16, expected level should be 10'
} // violation, 'level 8, expected level should be 4'
} // violation, 'level 4, expected level should be 2'
void method3(int a, // violation, 'level 4, expected level should be 2'
int b) {
if (x // violation, 'level 8, expected level should be 4'
&& y) {
method3(a, b); // violation, 'level 12, expected level should be 6'
} // violation, 'level 8, expected level should be 4'
} // violation, 'level 4, expected level should be 2'
// violation below 'level 4, expected level should be 2'
void handleValue(String aFooString,
int aFooInt) {
// violation below 'level 8, expected level should be 4'
boolean cond1,cond2,cond3,cond4,cond5,cond6;
// violation below 'level 8, expected level should be 4'
cond1=cond2=cond3=cond4=cond5=cond6=false;
if (cond1 // violation, 'level 8, expected level should be 4'
|| cond2) { // violation below 'level 12, expected level should be 6'
field = field.toUpperCase()
.concat(" TASK");
} // violation, 'level 8, expected level should be 4'
} // violation, 'level 4, expected level should be 2'
void methodBrace() // violation, 'level 4, expected level should be 2'
{ // violation, 'level 4, expected level should be 2'
} // violation, 'level 4, expected level should be 2'
}
To configure the check with custom lineWrappingIndentation (8 spaces instead of default 4):
<module name="Checker">
<module name="TreeWalker">
<module name="Indentation">
<property name="lineWrappingIndentation" value="8"/>
</module>
</module>
</module>
Example of code with lineWrappingIndentation set to 8:
class Example6 {
int a;
boolean x, y;
String field = "example";
int[] values = {
1, 2, 3
};
int[] values2 = {
10 // violation, 'level 2, expected level should be one of the following: 8, 12'
};
void method2()
throws Exception {
switch (a) {
case 1:
break;
case 2:
break;
}
}
void method3(int a,
int b) { // ok, lineWrappingIndentation = 8
if (x
&& y) {
method3(a, b);
}
}
void handleValue(String aFooString,
int aFooInt) {
boolean cond1,cond2,cond3,cond4,cond5,cond6;
cond1=cond2=cond3=cond4=cond5=cond6=false;
if (cond1
|| cond2) {
field = field.toUpperCase()
.concat(" TASK");
}
}
void methodBrace()
{
}
}
To configure the check with custom throwsIndent (8 spaces instead of default 4):
<module name="Checker">
<module name="TreeWalker">
<module name="Indentation">
<property name="throwsIndent" value="8"/>
</module>
</module>
</module>
Example of code with throwsIndent set to 8. Method 'processValues' has throws on a new line with only 4-space indent, which violates the configured 8-space throwsIndent. Method 'demonstrateSwitch' has throws on a new line with correct 8-space indent:
class Example7 {
int a;
boolean x, y;
String field = "example";
int[] values = {
1, 2, 3
};
int[] values2 = {
10 // violation, 'level 2, expected level should be 8'
};
void method2()
throws Exception { // violation, 'level 8, expected level should be 12'
switch (a) {
case 1:
break;
case 2:
break;
}
}
void method3(int a,
int b) {
if (x
&& y) {
method3(a, b);
}
}
void handleValue(String aFooString,
int aFooInt) { // indent:8 ; expected: > 4;
boolean cond1,cond2,cond3,cond4,cond5,cond6;
cond1=cond2=cond3=cond4=cond5=cond6=false;
if (cond1
|| cond2) {
field = field.toUpperCase()
.concat(" TASK");
}
}
void methodBrace()
{
}
}
To configure the check with custom arrayInitIndent (2 spaces instead of default 4):
<module name="Checker">
<module name="TreeWalker">
<module name="Indentation">
<property name="arrayInitIndent" value="2"/>
</module>
</module>
</module>
Example of code with arrayInitIndent set to 2:
class Example8 {
int a;
boolean x, y;
String field = "example";
int[] values = {
1, 2, 3
};
int[] values2 = {
10 // violation, 'level 2, expected level should be one of'
};
void method2()
throws Exception {
switch (a) {
case 1:
break;
case 2:
break;
}
}
void method3(int a,
int b) {
if (x
&& y) {
method3(a, b);
}
}
void handleValue(String aFooString,
int aFooInt) {
boolean cond1,cond2,cond3,cond4,cond5,cond6;
cond1=cond2=cond3=cond4=cond5=cond6=false;
if (cond1
|| cond2) {
field = field.toUpperCase()
.concat(" TASK");
}
}
void methodBrace()
{
}
}
To configure the check with custom braceAdjustment (2 spaces instead of default 0):
<module name="Checker">
<module name="TreeWalker">
<module name="Indentation">
<property name="braceAdjustment" value="2"/>
</module>
</module>
</module>
Example of code with braceAdjustment set to 2:
class Example9 {
int a;
boolean x, y;
String field = "example";
int[] values = {
1, 2, 3
};
int[] values2 = {
10 // violation, 'level 2, expected level should be 8'
};
void method2()
throws Exception {
switch (a) {
case 1: // ok, caseIndent = 4
break;
case 2:
break;
}
}
void method3(int a,
int b) {
if (x
&& y) {
method3(a, b);
}
}
void handleValue(String aFooString,
int aFooInt) {
boolean cond1,cond2,cond3,cond4,cond5,cond6;
cond1=cond2=cond3=cond4=cond5=cond6=false;
if (cond1
|| cond2) {
field = field.toUpperCase()
.concat(" TASK");
}
}
void methodBrace()
{ // violation, 'level 4, expected level should be 6'
} // violation, 'level 4, expected level should be 6'
}
Example of Usage
Violation Messages
All messages can be customized if the default message doesn't suit you. Please see the documentation to learn how to.
Fully Qualified Name
com.puppycrawl.tools.checkstyle.checks.indentation.IndentationCheck
Use this fully qualified class name in configuration when an exact class reference is required.






