Why Returning Null from Functions is a Bad Idea and What to Do Instead (2024)

In this article, we’ll explore the concept of returning null from functions in software development. We'll discuss why it's not a good practice, and suggest better alternatives to use instead.

When a variable or object reference is set to null, it means it does not point to any valid object or value. This can cause runtime errors such as NullReferenceExceptions, and is a common source of bugs in software development. One common source of null references is returning null from functions.

Returning null can cause several problems in software development. Firstly, it can cause NullReferenceExceptions. If the caller of a function that returns null is not aware of the possibility of a null return value, they may try to access a property or method on the null object, which will result in a NullReferenceException. This can be a frustrating and time-consuming bug to track down.

Secondly, it can make code harder to reason about. When a function returns null, the caller has to handle the possibility of a null value, which can complicate the code and make it harder to understand. This can lead to more bugs and more difficult debugging. Additionally, it violates the principle of least astonishment, which means that code should behave in a way that is predictable and consistent.

Finally, returning null can violate good software design principles. For example, the Single Responsibility Principle (SRP) states that each function or class should have only one responsibility. If afunction returns null, it is performing two responsibilities: returning data and indicating an error condition. This violates the SRP and can make code harder to maintain and modify.

Instead of returning null, there are several better alternatives that can be used:

  1. Return an empty collection: If the function is supposed to return a collection of items, returning an empty collection instead of null can be a good alternative. This way, the caller can still iterate over the collection without having to handle the possibility of a null value.
  2. Throw an exception: If the function encounters an error condition that it cannot handle, it can throw an exception instead of returning null. This alerts the caller to the error immediately and allows them to handle the exception appropriately.
  3. Return an optional value: Some programming languages provide the concept of an optional value, which can be used instead of returning null. An optional value is a type that can either contain a value or be empty. This way, the caller can use the optional value to check whether a value was returned or not, and handle the empty case appropriately.
  4. Use the Null Object pattern: This pattern involves creating a class that acts as a stand-in for null. This class implements the same interface as the expected return value and provides default or no-op implementations of the methods. This way, the caller can still use the returned object without having to handle a null value.
  5. Use assertions: Assertions are statements that checkif a certain condition is true at runtime. By using assertions in the function, the developer can ensure that the function will not return null, and if it does, the assertion will fail and alert the developer to the problem.

To illustrate these alternatives, let’s consider some examples with Java code:

  • Return an Empty Collection
public List<String> getNames() {
List<String> names = new ArrayList<>();
// code to populate the list
return names.isEmpty() ? Collections.emptyList() : names;
}

In this example, if the names list is empty, we return an empty list using the Collections.emptyList() method. This way, the caller can still iterate over the collection without having to handle the possibility of a null value.

  • Throw an Exception
public String getNameById(int id) throws IllegalArgumentException {
String name = // code to get the name by id
if (name == null) {
throw new IllegalArgumentException("Invalid id: " + id);
}
return name;
}

In this example, if the name variable is null, we throw an IllegalArgumentException with a descriptive message. This alerts the caller to the error immediately and allows them to handle the exception appropriately.

  • Return an Optional Value
public Optional<String> getNameById(int id) {
String name = // code to get the name by id
return Optional.ofNullable(name);
}

In this example, we use the Optional.ofNullable() method to create an optional value that can either contain a value or be empty. The caller can then use the optional value to check whether a value was returned or not, and handle the empty case appropriately.

  • Use the Null Object Pattern
public interface Animal {
void makeSound();
}

public class NullAnimal implements Animal {
@Override
public void makeSound() {
// do nothing
}
}
public class Dog implements Animal {
@Override
public void makeSound() {
System.out.println("Woof!");
}
}
public Animal getAnimalByName(String name) {
Animal animal = // code to get the animal by name
return animal != null ? animal : new NullAnimal();
}

In this example, we define an interface Animal with a method makeSound(). We also define a NullAnimal class that implements the Animal interface with a no-op implementation of makeSound(). In the getAnimalByName() method, if the animal variable is null, we return a NullAnimal() object instead. This way, the caller can still use the returned object without having to handle a null value.

  • Use Assertions
public String getNameById(int id) {
String name = // code to get the name by id
assert name != null : "Name should not be null";
return name;
}

In this example, we use an assertion to ensure that the name variable is not null. If it is null, the assertion will fail and alert the developer to the problem.

In conclusion, it’s best to avoid returning null from functions in software development. By returning an empty collection, throwing an exception, returning an optional value, using the Null Object pattern, or using assertions, developers can write more robust and maintainable code. Avoiding null references can lead to code that is easy to understand, modify, and maintain. By following these best practices, we can write better software that is less prone to bugs and errors.

Why Returning Null from Functions is a Bad Idea and What to Do Instead (2024)
Top Articles
Latest Posts
Article information

Author: Clemencia Bogisich Ret

Last Updated:

Views: 5940

Rating: 5 / 5 (60 voted)

Reviews: 83% of readers found this page helpful

Author information

Name: Clemencia Bogisich Ret

Birthday: 2001-07-17

Address: Suite 794 53887 Geri Spring, West Cristentown, KY 54855

Phone: +5934435460663

Job: Central Hospitality Director

Hobby: Yoga, Electronics, Rafting, Lockpicking, Inline skating, Puzzles, scrapbook

Introduction: My name is Clemencia Bogisich Ret, I am a super, outstanding, graceful, friendly, vast, comfortable, agreeable person who loves writing and wants to share my knowledge and understanding with you.