Method Design

This lesson describes the best practices to emulate when designing methods.

We'll cover the following...

Notes on Method Design

  1. For any publicly exported method always validate the input parameters to the method. For private or package private methods, asserts should suffice. Validation may not make sense if its is too expensive or is performed implicitly during computation. Additionally, always document the restrictions on input parameters for methods and constructors.

  2. It is critical to check the validity of constructor parameters to prevent the construction of an object that violates its class invariants.

  3. Create copies of mutable parameters passed in to constructors of immutable classes. An attacker can change a passed-in mutable object after invoking the constructor. Consider the following example where the DefensiveClass receives a collection of cryptographic keys in its constructor. The class incorrectly saves a reference to the collection which can be modified outside of the DefensiveClass as shown in the runnable snippet.

    class DefensiveClass {
    
        List<String> cryptoKeys;
    
        // Bad design!
        DefensiveClass(List<String> cryptoKeys) {
            this.cryptoKeys = cryptoKeys;
        }
    
        void printKeys() {
            for (String key : cryptoKeys) {
                System.out.println(key);
            }
        }
    }
    

    The suggestion isn't limited to only immutable classes in fact anytime you write a method or constructor that assigns a client-provided object to an internal data structure there exists the possibility of the client changing the passed-in object at a later time. The fix for the DefensiveClass class is to create a copy of the list of passed-in keys to the constructor. ...