This rule raises an issue when a concrete class is declared inside a Java interface.
In Java, interfaces can contain nested types, including classes. While this is syntactically valid, it goes against the fundamental purpose of interfaces, which is to define contracts rather than implementations.
Java interfaces are meant to define contracts - they specify what methods should be available without dictating how those methods work. When you declare a concrete class inside an interface, you’re mixing two different concerns:
This creates confusion about the role of the interface. Developers reading your code may struggle to understand why implementation details are bundled with contract definitions.
Additionally, this pattern can lead to:
While nested interfaces within interfaces are acceptable (since both define contracts), concrete classes belong in their own files where their implementation purpose is clear.
When concrete classes are declared inside interfaces, the code becomes harder to understand and maintain:
Move the inner class to a top-level class in its own file. This clearly separates the interface contract from the implementation.
public interface UserService {
void createUser(User user);
class UserValidator { // Noncompliant
public boolean isValid(User user) {
return user != null && user.getName() != null;
}
}
}
public interface UserService {
void createUser(User user);
}
// In a separate file: UserValidator.java
public class UserValidator {
public boolean isValid(User user) {
return user != null && user.getName() != null;
}
}