Since Checkstyle 8.16
Checks for implicit modifiers on nested types in classes and records.
This check is effectively the opposite of RedundantModifier. It checks the modifiers on nested types in classes and records, ensuring that certain modifiers are explicitly specified even though they are actually redundant.
Nested enums, interfaces, and records within a class are always static and as
such the compiler does not require the static modifier. This check provides
the ability to enforce that the static modifier is explicitly coded and not
implicitly added by the compiler.
public final class Person {
enum Age { // violation
CHILD, ADULT
}
}
Rationale for this check:
Nested enums, interfaces, and records are treated differently from nested classes as they
are only allowed to be static. Developers should not need to remember this
rule, and this check provides the means to enforce that the modifier is coded explicitly.
| name | description | type | default value | since |
|---|---|---|---|---|
| violateImpliedStaticOnNestedEnum |
Control whether to enforce that static is explicitly coded
on nested enums in classes and records. |
boolean | true |
8.16 |
| violateImpliedStaticOnNestedInterface |
Control whether to enforce that static is explicitly coded
on nested interfaces in classes and records. |
boolean | true |
8.16 |
| violateImpliedStaticOnNestedRecord |
Control whether to enforce that static is explicitly coded
on nested records in classes and records. |
boolean | true |
8.36 |
To configure the check so that it checks that all implicit modifiers on nested interfaces, enums, and records are explicitly specified in classes and records.
Configuration:
<module name="ClassMemberImpliedModifier" />
Code:
public final class Person {
static interface Address1 { // valid
}
interface Address2 { // violation
}
static enum Age1 { // valid
CHILD, ADULT
}
enum Age2 { // violation
CHILD, ADULT
}
public static record GoodRecord() {} // valid
public record BadRecord() {} // violation
public static record OuterRecord() {
static record InnerRecord1(){} // valid
record InnerRecord2(){} // violation
}
}
All messages can be customized if the default message doesn't suit you. Please see the documentation to learn how to.
com.puppycrawl.tools.checkstyle.checks.modifier
Since Checkstyle 8.12
Checks for implicit modifiers on interface members and nested types.
This check is effectively the opposite of RedundantModifier. It checks the modifiers on interface members, ensuring that certain modifiers are explicitly specified even though they are actually redundant.
Methods in interfaces are public by default, however from Java 9
they can also be private. This check provides the ability to enforce
that public is explicitly coded and not implicitly added by the compiler.
From Java 8, there are three types of methods in interfaces - static methods
marked with static, default methods marked with default and
abstract methods which do not have to be marked with anything.
From Java 9, there are also private methods marked with private.
This check provides the ability to enforce that abstract is explicitly
coded and not implicitly added by the compiler.
Fields in interfaces are always public static final and as such the
compiler does not require these modifiers. This check provides the ability to
enforce that these modifiers are explicitly coded and not implicitly added by
the compiler.
Nested types within an interface are always public static and as such the
compiler does not require the public static modifiers. This check provides
the ability to enforce that the public and static modifiers
are explicitly coded and not implicitly added by the compiler.
public interface AddressFactory {
// check enforces code contains "public static final"
public static final String UNKNOWN = "Unknown";
String OTHER = "Other"; // violation
// check enforces code contains "public" or "private"
public static AddressFactory instance();
// check enforces code contains "public abstract"
public abstract Address createAddress(String addressLine, String city);
List<Address> findAddresses(String city); // violation
// check enforces default methods are explicitly declared "public"
public default Address createAddress(String city) {
return createAddress(UNKNOWN, city);
}
default Address createOtherAddress() { // violation
return createAddress(OTHER, OTHER);
}
}
Rationale for this check: Methods, fields and nested types are treated differently depending on whether they are part of an interface or part of a class. For example, by default methods are package-scoped on classes, but public in interfaces. However, from Java 8 onwards, interfaces have changed to be much more like abstract classes. Interfaces now have static and instance methods with code. Developers should not have to remember which modifiers are required and which are implied. This check allows the simpler alternative approach to be adopted where the implied modifiers must always be coded explicitly.
| name | description | type | default value | since |
|---|---|---|---|---|
| violateImpliedPublicField |
Control whether to enforce that public is explicitly coded
on interface fields. |
boolean | true |
8.12 |
| violateImpliedStaticField |
Control whether to enforce that static is explicitly coded
on interface fields. |
boolean | true |
8.12 |
| violateImpliedFinalField |
Control whether to enforce that final is explicitly coded
on interface fields. |
boolean | true |
8.12 |
| violateImpliedPublicMethod |
Control whether to enforce that public is explicitly coded
on interface methods. |
boolean | true |
8.12 |
| violateImpliedAbstractMethod |
Control whether to enforce that abstract is explicitly coded
on interface methods. |
boolean | true |
8.12 |
| violateImpliedPublicNested |
Control whether to enforce that public is explicitly coded
on interface nested types. |
boolean | true |
8.12 |
| violateImpliedStaticNested |
Control whether to enforce that static is explicitly coded
on interface nested types. |
boolean | true |
8.12 |
To configure the check so that it checks that all implicit modifiers on methods, fields and nested types are explicitly specified in interfaces.
Configuration:
<module name="InterfaceMemberImpliedModifier"/>
Code:
public interface AddressFactory {
public static final String UNKNOWN = "Unknown"; // valid
String OTHER = "Other"; // violation
public static AddressFactory instance(); // valid
public abstract Address createAddress(String addressLine, String city); // valid
List<Address> findAddresses(String city); // violation
interface Address { // violation
String getCity(); // violation
}
}
This example checks that all implicit modifiers on methods and fields are explicitly specified, but nested types do not need to be.
Configuration:
<module name="InterfaceMemberImpliedModifier">
<property name="violateImpliedPublicNested" value="false"/>
<property name="violateImpliedStaticNested" value="false"/>
</module>
Code:
public interface RoadFeature {
String STOP = "Stop"; // violation
enum Lights { // valid because of configured properties
RED, YELLOW, GREEN;
}
}
All messages can be customized if the default message doesn't suit you. Please see the documentation to learn how to.
com.puppycrawl.tools.checkstyle.checks.modifier
Since Checkstyle 3.0
Checks that the order of modifiers conforms to the suggestions in the Java Language specification, § 8.1.1, 8.3.1, 8.4.3 and 9.4. The correct order is:
public
protected
private
abstract
default
static
sealed
non-sealed
final
transient
volatile
synchronized
native
strictfp
In additional, modifiers are checked to ensure all annotations are declared before all other modifiers.
Rationale: Code is easier to read if everybody follows a standard.
ATTENTION: We skip type annotations from validation.
To configure the check:
<module name="ModifierOrder"/>
All messages can be customized if the default message doesn't suit you. Please see the documentation to learn how to.
com.puppycrawl.tools.checkstyle.checks.modifier
Since Checkstyle 3.0
Checks for redundant modifiers.
Rationale: The Java Language Specification strongly
discourages the usage of public and abstract for method
declarations in interface definitions as a matter of style.
The check validates:
public
or static.
enum definitions that are declared
as static.
record definitions that are declared as final and nested
record definitions that are declared as static.
interfaces by definition are abstract so the abstract modifier is
redundant on them.
Type declarations nested under interfaces by definition are public and static,
so the public and static modifiers on nested type
declarations are redundant. On the other hand, classes inside of interfaces can
be abstract or non abstract. So, abstract modifier is allowed.
Fields in interfaces and annotations are automatically public, static and final, so these modifiers are redundant as well.
As annotations are a form of interface, their fields are also automatically public, static and final just as their annotation fields are automatically public and abstract.
A record class is implicitly final and cannot be abstract, these restrictions emphasize that the API of a record class is defined solely by its state description, and cannot be enhanced later by another class. Nested records are implicitly static. This avoids an immediately enclosing instance which would silently add state to the record class. See JEP 395 for more info.
Enums by definition are static implicit subclasses of java.lang.Enum<E>.
So, the static modifier on the enums is redundant. In addition,
if enum is inside of interface, public modifier is also redundant.
Enums can also contain abstract methods and methods which can be overridden by the declared enumeration fields. See the following example:
public enum EnumClass {
FIELD_1,
FIELD_2 {
@Override
public final void method1() {} // violation expected
};
public void method1() {}
public final void method2() {} // no violation expected
}
Since these methods can be overridden in these situations, the final methods are not marked as redundant even though they can't be extended by other classes/enums.
Nested enum types are always static by default.
Final classes by definition cannot be extended so the final
modifier on the method of a final class is redundant.
Public modifier for constructors in non-public non-protected classes is always obsolete:
public class PublicClass {
public PublicClass() {} // OK
}
class PackagePrivateClass {
public PackagePrivateClass() {} // violation expected
}
There is no violation in the following example, because removing public modifier from ProtectedInnerClass constructor will make this code not compiling:
package a;
public class ClassExample {
protected class ProtectedInnerClass {
public ProtectedInnerClass () {}
}
}
package b;
import a.ClassExample;
public class ClassExtending extends ClassExample {
ProtectedInnerClass pc = new ProtectedInnerClass();
}
| name | description | type | default value | since |
|---|---|---|---|---|
| tokens | tokens to check | subset of tokens METHOD_DEF , VARIABLE_DEF , ANNOTATION_FIELD_DEF , INTERFACE_DEF , CTOR_DEF , CLASS_DEF , ENUM_DEF , RESOURCE , ANNOTATION_DEF , RECORD_DEF . | METHOD_DEF , VARIABLE_DEF , ANNOTATION_FIELD_DEF , INTERFACE_DEF , CTOR_DEF , CLASS_DEF , ENUM_DEF , RESOURCE , ANNOTATION_DEF , RECORD_DEF . | 3.0 |
To configure the check:
<module name="RedundantModifier"/>
To configure the check to check only methods and not variables:
<module name="RedundantModifier">
<property name="tokens" value="METHOD_DEF"/>
</module>
All messages can be customized if the default message doesn't suit you. Please see the documentation to learn how to.
com.puppycrawl.tools.checkstyle.checks.modifier