> For the complete documentation index, see [llms.txt](https://petozoltan.gitbook.io/clearcode/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://petozoltan.gitbook.io/clearcode/clean-code/clean-code-outline/nulls-and-validity-checks.md).

# Nulls and Validity Checks

### Avoid NullPointerExceptions (NPE)

* Check at the beginning - *Unhappy path, Happy path*
* Consider using helper methods
* Check each object which is de-referenced in the method - and only these ones

Example: Bad: Null check at the wrong place

```java
void doSomething(MyClass input) {
    if(input != null) { // Unnecessary here
        doStuff(input);
    }
}

void doStuff(MyClass input) {
    input.setData(10); // Would be necessary here
}
```

Example: Good: Null check always and only when dereferencing

```java
void doSomething(MyClass input) {
    doStuff(input);
}

void doStuff(MyClass input) {
    if(input == null) {
        return;
    }
    input.setData(10);
}
```

### Defensive Programming

Also known as Secure Programming. A larger topic, but some elements:

#### Inputs

* Never trust data coming from outside - *user input, external systems*
* Fail early, Fail clean
* Create and use immutable types

#### Outputs

* Do not modify a data through getters
* Prevent it if possible - *unmodifiable collections*
* Create and use immutable types

Example: Bad: Unclear validity check

```java
// What to do when input source is null?
// Why is the entire content indented?
public final void parse(final Config[] configs, final boolean flushAfterParse) {
    if (getInputSource() != null) {
        final EdifactParser parser = new EdifactParser(getInputSource(), getHandler());
        for (final Config config : configs) {
            parser.addConfig(config);
        }
        parser.convert();
        if (flushAfterParse) {
            getHandler().flush(true);
        }
    }
}
```

Example: Good: Validity check at the beginning

```java
public final void parse(final Config[] configs, final boolean flushAfterParse) {
    // Unhappy path
    if (getInputSource() == null) {
        return; // Do nothing, return default or throw exception
    }
    // Happy path or Normal flow
    final EdifactParser parser = new EdifactParser(getInputSource(), getHandler());
    for (final Config config : configs) {
        parser.addConfig(config);
    }
    parser.convert();
    if (flushAfterParse) {
        getHandler().flush(true);
    }
}
```

### Parameters

* Do not pass explicitly null - *it is a "cheating", \_allow it with an overloaded method*

### Unit Test of Inputs

* Unit test will nulls and empty values in all possible ways
  * null object
  * entire collection or array is null
  * collection or array element is null

### Error Handling

* Do not return null - *rather throw exception*

> Things must not be multiplied beyond necessity. The simplest solution is the best. (Occam’s Razor)
