diff --git a/src/main/java/com/puppycrawl/tools/checkstyle/checks/modifier/RedundantModifierCheck.java b/src/main/java/com/puppycrawl/tools/checkstyle/checks/modifier/RedundantModifierCheck.java
index af06aa17e..1307197ef 100644
--- a/src/main/java/com/puppycrawl/tools/checkstyle/checks/modifier/RedundantModifierCheck.java
+++ b/src/main/java/com/puppycrawl/tools/checkstyle/checks/modifier/RedundantModifierCheck.java
@@ -29,15 +29,40 @@ import com.puppycrawl.tools.checkstyle.api.DetailAST;
import com.puppycrawl.tools.checkstyle.api.TokenTypes;
/**
- * Checks for redundant modifiers in interface and annotation definitions.
- * Checks for non public class constructor and enum constructor redundant modifier.
- * Checks for redundant final modifiers on methods of final classes.
- * Checks for redundant static modifiers on nested enums.
+ * Checks for redundant modifiers in interface and annotation definitions,
+ * final modifier on methods of final classes, inner interface
+ * declarations that are declared as static, non public class
+ * constructors and enum constructors, nested enum definitions that are declared
+ * as static.
*
- *
Examples:
+ *Interfaces by definition are abstract so the abstract
+ * modifier on the interface is redundant.
+ *
+ *
Classes inside of interfaces by definition are public and static,
+ * so the public and static modifiers
+ * on the inner classes 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.
+ * + *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.
+ *
+ *
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:
* *
- * {@code
* public class PublicClass {
* public PublicClass() {} // OK
* }
@@ -45,36 +70,30 @@ import com.puppycrawl.tools.checkstyle.api.TokenTypes;
* 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:
+ * *
- * {@code
* package a;
- * public class ClassWithProtectedInnerClass {
- * protected class ProtectedClass {
- * public ProtectedClass () {} // OK
+ * public class ClassExample {
+ * protected class ProtectedInnerClass {
+ * public ProtectedInnerClass () {}
* }
* }
- * }
- *
- * - * in this example is no violation because removing public from - * ProtectedClass constructor modifier will make this example - * not compiling: - *
- *
- * {@code
+ *
* package b;
- * import a.ClassWithProtectedInnerClass;
- * public class ClassExtending extends ClassWithProtectedInnerClass {
- * ProtectedClass pc = new ProtectedClass();
- * }
+ * import a.ClassExample;
+ * public class ClassExtending extends ClassExample {
+ * ProtectedInnerClass pc = new ProtectedInnerClass();
* }
*
*
* @author lkuehne
* @author liscju
+ * @author Andrei Selkin
* @author Vladislav Lisetskiy
*/
public class RedundantModifierCheck
@@ -208,6 +227,7 @@ public class RedundantModifierCheck
|| type == TokenTypes.LITERAL_STATIC
&& ast.getType() != TokenTypes.METHOD_DEF
|| type == TokenTypes.ABSTRACT
+ && ast.getType() != TokenTypes.CLASS_DEF
|| type == TokenTypes.FINAL) {
log(modifier.getLineNo(), modifier.getColumnNo(),
MSG_KEY, modifier.getText());
diff --git a/src/test/java/com/puppycrawl/tools/checkstyle/checks/modifier/RedundantModifierTest.java b/src/test/java/com/puppycrawl/tools/checkstyle/checks/modifier/RedundantModifierTest.java
index 00031f38e..45c579ea0 100644
--- a/src/test/java/com/puppycrawl/tools/checkstyle/checks/modifier/RedundantModifierTest.java
+++ b/src/test/java/com/puppycrawl/tools/checkstyle/checks/modifier/RedundantModifierTest.java
@@ -33,6 +33,20 @@ import com.puppycrawl.tools.checkstyle.api.TokenTypes;
public class RedundantModifierTest
extends BaseCheckTestSupport {
+
+ @Test
+ public void testClassesInsideOfInterfaces() throws Exception {
+ final DefaultConfiguration checkConfig =
+ createCheckConfig(RedundantModifierCheck.class);
+ final String[] expected = {
+ "11:5: " + getCheckMessage(MSG_KEY, "static"),
+ "17:5: " + getCheckMessage(MSG_KEY, "public"),
+ "20:5: " + getCheckMessage(MSG_KEY, "public"),
+ "26:5: " + getCheckMessage(MSG_KEY, "static"),
+ };
+ verify(checkConfig, getPath("InputModifierClassesInsideOfInterfaces.java"), expected);
+ }
+
@Test
public void testIt() throws Exception {
final DefaultConfiguration checkConfig =
diff --git a/src/test/resources-noncompilable/com/puppycrawl/tools/checkstyle/InputFinalInDefaultMethods.java b/src/test/resources-noncompilable/com/puppycrawl/tools/checkstyle/InputFinalInDefaultMethods.java
index 20d9733c3..b6ddca54a 100644
--- a/src/test/resources-noncompilable/com/puppycrawl/tools/checkstyle/InputFinalInDefaultMethods.java
+++ b/src/test/resources-noncompilable/com/puppycrawl/tools/checkstyle/InputFinalInDefaultMethods.java
@@ -1,6 +1,6 @@
//Compilable with Java8
public interface MyInterface {
- final int k = 5; //WARNING
+ final int k = 5; // violation
default int defaultMethod(final int x) {
if (k == 5) {
diff --git a/src/test/resources/com/puppycrawl/tools/checkstyle/InputModifier.java b/src/test/resources/com/puppycrawl/tools/checkstyle/InputModifier.java
index a0eaa3119..52f7ab115 100644
--- a/src/test/resources/com/puppycrawl/tools/checkstyle/InputModifier.java
+++ b/src/test/resources/com/puppycrawl/tools/checkstyle/InputModifier.java
@@ -51,32 +51,32 @@ strictfp final class InputModifier // illegal order of modifiers for class
}
/** holder for redundant 'public' modifier check. */
- public static interface InputRedundantPublicModifier
+ public static interface InputRedundantPublicModifier // violation
{
/** redundant 'public' modifier */
- public void a();
+ public void a(); // violation
/** all OK */
void b();
/** redundant abstract modifier */
- abstract void c();
+ abstract void c(); // violation
/** redundant 'public' modifier */
- public float PI_PUBLIC = (float) 3.14;
+ public float PI_PUBLIC = (float) 3.14; // violation
/** redundant 'abstract' modifier (field can not be abstract) */
// abstract float PI_ABSTRACT = (float) 3.14;
/** redundant 'final' modifier */
- final float PI_FINAL = (float) 3.14;
+ final float PI_FINAL = (float) 3.14; // violation
/** all OK */
float PI_OK = (float) 3.14;
}
/** redundant 'final' modifier */
- private final void method()
+ private final void method() // violation
{
}
}
@@ -85,7 +85,7 @@ strictfp final class InputModifier // illegal order of modifiers for class
final class RedundantFinalClass
{
/** redundant 'final' modifier */
- public final void finalMethod()
+ public final void finalMethod() // violation
{
}
@@ -96,7 +96,7 @@ final class RedundantFinalClass
}
/** Holder for redundant modifiers of inner implementation */
-abstract interface InnerImplementation
+abstract interface InnerImplementation // violation
{
InnerImplementation inner =
new InnerImplementation()
@@ -113,12 +113,12 @@ abstract interface InnerImplementation
/** Holder for redundant modifiers of annotation fields/variables */
@interface Annotation
{
- public String s1 = "";
- final String s2 = "";
- static String s3 = "";
+ public String s1 = ""; // violation
+ final String s2 = ""; // violation
+ static String s3 = ""; // violation
String s4 = "";
- public String blah();
- abstract String blah2();
+ public String blah(); // violation
+ abstract String blah2(); // violation
}
@interface MyAnnotation2 {
diff --git a/src/test/resources/com/puppycrawl/tools/checkstyle/InputModifierClassesInsideOfInterfaces.java b/src/test/resources/com/puppycrawl/tools/checkstyle/InputModifierClassesInsideOfInterfaces.java
new file mode 100644
index 000000000..e7042cdde
--- /dev/null
+++ b/src/test/resources/com/puppycrawl/tools/checkstyle/InputModifierClassesInsideOfInterfaces.java
@@ -0,0 +1,31 @@
+package com.puppycrawl.tools.checkstyle;
+
+public interface InputModifierClassesInsideOfInterfaces {
+
+ // Class inside of interface can be abstract and non abstract, but always public static.
+ abstract class A {}
+
+ class B {}
+
+ // All classes inside interfaces are public static classes, and static modifier is redundant.
+ static class C { // violation
+ public static boolean verifyState( A a ) {
+ return true;
+ }
+ }
+
+ public class E {} // violation
+
+ // Enums are static implicit subclasses of Enum class.
+ public enum Role1 { // violation
+ ADMIN,
+ EDITOR,
+ VANILLA;
+ }
+
+ static enum Role2 { // violation
+ ADMIN,
+ EDITOR,
+ VANILLA;
+ }
+}
diff --git a/src/test/resources/com/puppycrawl/tools/checkstyle/InputRedundantConstructorModifier.java b/src/test/resources/com/puppycrawl/tools/checkstyle/InputRedundantConstructorModifier.java
index 29b16d3cf..66e76728a 100644
--- a/src/test/resources/com/puppycrawl/tools/checkstyle/InputRedundantConstructorModifier.java
+++ b/src/test/resources/com/puppycrawl/tools/checkstyle/InputRedundantConstructorModifier.java
@@ -7,7 +7,7 @@ package com.puppycrawl.tools.checkstyle;
public enum InputRedundantConstructorModifier {
VAL1, VAL2;
- private InputRedundantConstructorModifier() { }
+ private InputRedundantConstructorModifier() { } // violation
InputRedundantConstructorModifier(int i) { }
diff --git a/src/test/resources/com/puppycrawl/tools/checkstyle/InputRedundantStaticModifierInInnerTypeOfInterface.java b/src/test/resources/com/puppycrawl/tools/checkstyle/InputRedundantStaticModifierInInnerTypeOfInterface.java
index eab97cabe..8e7a8c6cb 100644
--- a/src/test/resources/com/puppycrawl/tools/checkstyle/InputRedundantStaticModifierInInnerTypeOfInterface.java
+++ b/src/test/resources/com/puppycrawl/tools/checkstyle/InputRedundantStaticModifierInInnerTypeOfInterface.java
@@ -5,11 +5,11 @@
package com.puppycrawl.tools.checkstyle;
public interface InputRedundantStaticModifierInInnerTypeOfInterface {
- static class MyInnerClass { }
+ static class MyInnerClass { } // violation
class MyInnerClass2 { }
- static enum MyInnerEnum { }
+ static enum MyInnerEnum { } // violation
enum MyInnerEnum2 { }
}
diff --git a/src/xdocs/checks.xml b/src/xdocs/checks.xml
index dc8d1bd7f..413bd4572 100644
--- a/src/xdocs/checks.xml
+++ b/src/xdocs/checks.xml
@@ -617,7 +617,11 @@
interface
+ declarations that are declared as static, non public class
+ constructors and enum constructors, nested enum definitions that are declared
+ as static.
- Variables in interfaces and annotations are automatically
+ Classes inside of interfaces by definition are public and static,
+ so the public and static modifiers
+ on the inner classes 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.
@@ -134,14 +142,20 @@
- Final classes by definition cannot be extended so the final
- modifier on the method of a final class is redundant.
+ 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.
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: @@ -157,22 +171,23 @@ } -
For non-public protected classes public modifier is not obsolete, - removing public from this example will make code not compiling: +
There is no violation in the following example, + because removing public modifier from ProtectedInnerClass + constructor will make this code not compiling: