Design Rules ("rulesets/design.xml")

AbstractClassWithoutAbstractMethod Rule

Since CodeNarc 0.12

The abstract class does not contain any abstract methods. An abstract class suggests an incomplete implementation, which is to be completed by subclasses implementing the abstract methods. If the class is intended to be used as a base class only (not to be instantiated directly) a protected constructor can be provided prevent direct instantiation.

Example:

    public abstract class MyBaseClass {
        void method1() {  }
        void method2() {  }
        // consider using abstract methods or removing
        // the abstract modifier and adding protected constructors
    }

The following examples all pass:

    abstract class MyClass extends AbstractParent {
        // OK because parent is named Abstract.*
    }
    abstract class MyClass extends BaseParent{
        // OK because parent is named Base.*
    }

CloseWithoutCloseable Rule

Since CodeNarc 0.12

If a class defines a "void close()" then that class should implement java.io.Closeable.

ConstantsOnlyInterface Rule

Since CodeNarc 0.12

An interface should be used only to model a behaviour of a class: using an interface as a container of constants is a poor usage pattern. Example:

    public interface ConstantsInterface {
        public static final int CONSTANT_1 = 0
        public static final String CONSTANT_2 = "1"
    }

EmptyMethodInAbstractClass Rule

Since CodeNarc 0.12

An empty method in an abstract class should be abstract instead, as developer may rely on this empty implementation rather than code the appropriate one.

    abstract class MyClass {
        def couldBeAbstract_1() {
            return null  // Should be abstract method
        }

        void couldBeAbstract_2() {
            // Should be abstract method
        }
    }

ImplementationAsType Rule

Checks for use of the following concrete classes when specifying the type of a method parameter, closure parameter, constructor parameter, method return type or field type. The corresponding interfaces should be used to specify the type instead.

  • java.util.ArrayList
  • java.util.GregorianCalendar
  • java.util.HashMap
  • java.util.HashSet
  • java.util.Hashtable
  • java.util.LinkedHashMap
  • java.util.LinkedHashSet
  • java.util.LinkedList
  • java.util.TreeMap
  • java.util.TreeSet
  • java.util.Vector
  • java.util.concurrent.ArrayBlockingQueue
  • java.util.concurrent.ConcurrentHashMap
  • java.util.concurrent.ConcurrentLinkedQueue
  • java.util.concurrent.CopyOnWriteArrayList
  • java.util.concurrent.CopyOnWriteArraySet
  • java.util.concurrent.DelayQueue
  • java.util.concurrent.LinkedBlockingQueue
  • java.util.concurrent.PriorityBlockingQueue
  • java.util.concurrent.PriorityQueue
  • java.util.concurrent.SynchronousQueue

Here are examples of code that produces violations:

    // Method parameter
    void myMethod(ArrayList list) {                   // violation
        ...
    }

    // Constructor parameter
    class MyClass {
        MyClass(java.util.HashSet set) {              // violation
            ...
        }
    }

    // Closure parameter
    def closure = { PriorityQueue queue -> ... }      // violation

    // Method return type
    GregorianCalendar calculateDate(int num) {        // violation
        ...
    }

    // Field type
    class MyClass {
        Hashtable map                                 // violation
    }

FinalClassWithProtectedMember Rule

Since CodeNarc 0.12

This rule finds classes marked final that contain protected members. If a class is final then it may not be subclassed, and there is therefore no point in having a member with protected visibility. Either the class should not be final or the member should be private or protected.