# Make Fields And Variables Final
# Description
This rule declares private
fields and local variables final
, if they are effectively final
.
The criteria for being effectively final
are as follows:
- The variable or field is not assigned after its initialisation
- Initialisation of non-
static
fields:- At the declaration OR
- In a non-
static
class initialiser OR - In ALL constructors of the class
- Initialisation of
static
fields:- At the declaration OR
- In a
static
initialiser
# Benefits
Readability and maintainability of code is improved and accidental reassignments are prevented for affected fields and variables.
# Tags
Tags
# Code Changes
# Assignments
Pre
public class MakeFinal {
private String nonStaticField = "nonStaticField";
private String nonStaticFieldEffectivelyFinal ="nonStaticFieldEffectivelyFinal";
private static String staticField = "staticField";
private static String staticFieldEffectivelyFinal = "staticFieldEffectivelyFinal";
public void localVariables() {
int i = 0;
int j = 0;
System.out.println(i);
System.out.println(j++);
}
public void nonStaticFields() {
nonStaticField += "Altered";
System.out.println(nonStaticField);
System.out.println(nonStaticFieldEffectivelyFinal);
}
public static void staticFields() {
staticField = staticField + "Altered";
System.out.println(staticField);
System.out.println(staticFieldEffectivelyFinal);
}
}
Post
public class MakeFinal {
private String nonStaticField ="nonStaticField";
private final String nonStaticFieldEffectivelyFinal ="nonStaticFieldEffectivelyFinal";
private static String staticField = "staticField";
private static final String staticFieldEffectivelyFinal = "staticFieldEffectivelyFinal";
public void localVariables() {
final int i = 0;
int j = 0;
System.out.println(i);
System.out.println(j++);
}
public void nonStaticFields() {
nonStaticField += "Altered";
System.out.println(nonStaticField);
System.out.println(nonStaticFieldEffectivelyFinal);
}
public static void staticFields() {
staticField = staticField + "Altered";
System.out.println(staticField);
System.out.println(staticFieldEffectivelyFinal);
}
}
# static
Field Initialisation
Pre
public class MakeFinal {
private static String initInDeclaration = "initInDeclaration";
private static String initInStaticInitialiser;
private static String initInDeclarationAndStaticInitialiser = "initInDeclarationAndStaticInitialiser";
private static String noInit;
static {
initInStaticInitialiser = "initInStaticInitialiser";
initInDeclarationAndStaticInitialiser = "initInDeclarationAndStaticInitialiser";
}
...
}
Post
public class MakeFinal {
private static final String initInDeclaration = "initInDeclaration";
private static final String initInStaticInitialiser;
private static String initInDeclarationAndStaticInitialiser = "initInDeclarationAndStaticInitialiser";
private static String noInit;
static {
initInStaticInitialiser = "initInStaticInitialiser";
initInDeclarationAndStaticInitialiser = "initInDeclarationAndStaticInitialiser";
}
...
}
# Non-static
Field Initialisation
Pre
public class MakeFinal {
private String initInDeclaration = "initInDeclaration";
private String initInClassInitialiser;
private String initInAllConstructors;
private String initInOneConstructorOnly;
private String initInDeclarationAndClassInitialiser = "initInDeclarationAndClassInitialiser";
private String noInit;
{
initInClassInitialiser = "initInClassInitialiser";
initInDeclarationAndClassInitialiser = "initInDeclarationAndClassInitialiser";
}
public MakeFinal() {
initInAllConstructors = "initInAllConstructors";
initInOneConstructorOnly = "initInOneConstructorOnly";
}
public MakeFinal(String arg1) {
initInAllConstructors = "initInAllConstructors";
}
...
}
Post
public class MakeFinal {
private final String initInDeclaration = "initInDeclaration";
private final String initInClassInitialiser;
private final String initInAllConstructors;
private String initInOneConstructorOnly;
private String initInDeclarationAndClassInitialiser = "initInDeclarationAndClassInitialiser";
private String noInit;
{
initInClassInitialiser = "initInClassInitialiser";
initInDeclarationAndClassInitialiser = "initInDeclarationAndClassInitialiser";
}
public MakeFinal() {
initInAllConstructors = "initInAllConstructors";
initInOneConstructorOnly = "initInOneConstructorOnly";
}
public MakeFinal(String arg1) {
initInAllConstructors = "initInAllConstructors";
}
...
}
# Limitations
This rule only affects private
fields and local variables at the moment. public
, protected
or package-private fields as well as method parameters are not considered yet.
You Want To Have Those Changes Done Automatically?
The automatic application of this rule is supported in the following jSparrow version:
# Properties
Property | Value |
---|---|
Rule ID | MakeFieldsAndVariablesFinal |
First seen in jSparrow version | 3.12.0 |
Minimum Java version | 1.1 |
Remediation cost | 5 min |