I'm trying to avoid overdo null checks, but at the same time I want to make null check whenever it needs to make the code robust. But sometimes I feel like it starts to be so much defensive since I don't implement API. Then I avoid some null-checks but when I start unit tests, it starts to always wait for runtime exceptions. What is the right approach, how to feel the balance. Here are the notes I have collected so far:
- avoid unnecessary null-checks in private methods of the instance class since proper null checks are made before and instance class is responsible of this, not each function
- make null checks in public methods and explain function behavior in the Contract for the public usage
- make null checks in the constructor
Let me give an dummy example where my confusing starts:
Here is the default function of the interface:
default void someFunction() {
// instantiaded foo and filters
foo = processFoo(foo, filters);
// do some operations with foo
// null check if processFoo's contract returns null (description in the implementation)
}
Implementation:
Foo processFoo(foo, filters) {
// Should I null check foo and filters?
// Operations with foo.someFields
// Operations with filters.someFields
return foo; // If I null check then I should return some exception or null to the caller function.
// If I don't null check just return received foo.
}