int is a primitive, null is not a value that it can take on. You could change the method return type to return java.lang.Integer and then you can return null, and existing code that returns int will get autoboxed.

Nulls are assigned only to reference types, it means the reference doesn't point to anything. Primitives are not reference types, they are values, so they are never set to null.

Using the object wrapper java.lang.Integer as the return value means you are passing back an Object and the object reference can be null.

Answer from Nathan Hughes on Stack Overflow
Top answer
1 of 16
103

StackOverflow has a good discussion about this exact topic in this Q&A. In the top rated question, kronoz notes:

Returning null is usually the best idea if you intend to indicate that no data is available.

An empty object implies data has been returned, whereas returning null clearly indicates that nothing has been returned.

Additionally, returning a null will result in a null exception if you attempt to access members in the object, which can be useful for highlighting buggy code - attempting to access a member of nothing makes no sense. Accessing members of an empty object will not fail meaning bugs can go undiscovered.

Personally, I like to return empty strings for functions that return strings to minimize the amount of error handling that needs to be put in place. However, you'll need to make sure that the group that your working with will follow the same convention - otherwise the benefits of this decision won't be achieved.

However, as the poster in the SO answer noted, nulls should probably be returned if an object is expected so that there is no doubt about whether data is being returned.

In the end, there's no single best way of doing things. Building a team consensus will ultimately drive your team's best practices.

2 of 16
102

In all the code I write, I avoid returning null from a function. I read that in Clean Code.

The problem with using null is that the person using the interface doesn't know if null is a possible outcome, and whether they have to check for it, because there's no not null reference type.

In F# you can return an option type, which can be some(Person) or none, so it's obvious to the caller that they have to check.

The analogous C# (anti-)pattern is the Try... method:

public bool TryFindPerson(int personId, out Person result);

Now I know people have said they hate the Try... pattern because having an output parameter breaks the ideas of a pure function, but it's really no different than:

class FindResult<T>
{
   public FindResult(bool found, T result)
   {
       this.Found = found;
       this.Result = result;
   }

   public bool Found { get; private set; }
   // Only valid if Found is true
   public T Result { get; private set;
}

public FindResult<Person> FindPerson(int personId);

...and to be honest you can assume that every .NET programmer knows about the Try... pattern because it's used internally by the .NET framework. That means they don't have to read the documentation to understand what it does, which is more important to me than sticking to some purist's view of functions (understanding that result is an out parameter, not a ref parameter).

So I'd go with TryFindPerson because you seem to indicate it's perfectly normal to be unable to find it.

If, on the other hand, there's no logical reason that the caller would ever provide a personId that didn't exist, I would probably do this:

public Person GetPerson(int personId);

...and then I'd throw an exception if it was invalid. The Get... prefix implies that the caller knows it should succeed.

Top answer
1 of 12
77
It's an old solution to a problem that happened way before Java. I'm old, but I still use it because it's memory efficient and fast. Situational example.. You have a function that returns an int. If you know its always supposed to be positive, it's pretty common to return -1 to communicate that something went wrong, is absent, isn't finished doing something, etc. It's quick. Only requires a single 32/64 bit piece of memory. Solid choice to use when documented well. Instead of integer, let's say you have a class that hypothetically takes up 200 bytes of memory. I don't want to just stop my program because something isn't in a list, and I can't just return -1. I could create a default class that represents a problem just like "-1" does, but that's going to allocate 200 bytes. Assigning the variable to 'null' doesn't allocate 200 bytes. It just points to a universal 'null' memory address that is well understood by the JVM to mean "nothing." "Nothing" saves space and saves a lot of computation power from .equals(...) and even garbage collection. Is it worth having to rely on performing a null check constantly? Actually, yes. It is usually worth it. If people are used to dealing with null, it's not a problem. Coming from different languages where null is not allowed, you get a lot of NullPointerExceptions. Skill issue, though. Edit: Removed most mentions of exceptions to focus on why a new programmer might see "return null" and to appease the Spring devs who believe checked exceptions are relative to OPs question.
2 of 12
6
In some functions, if you can't find the value you want to return, you might return null instead. For example, imagine you have a method that is meant to search for an object in a collection that fits certain criteria. If your collection does not contain such an object, then your method might handle that by returning null. Generally though, this would not be considered great software design. It is very easy to run into runtime errors this way, for example, if a developer using such a method does not realize that it could return null.
🌐
Medium
medium.com › javarevisited › just-dont-return-null-dcdf5d77128f
Just Don’t Return null!
February 16, 2022 - Return a “Special Case” object A special case object is something that we return instead of returning null. There’s a pattern called null value object which I have already explained in the other article so I am not going to explain it here again but instead, I am going to use Java 8 Optional.empty() which is just Java’s implementation of that patter.
🌐
Upwork
upwork.com › resources › articles › {name}
Null in Java: Understanding the Basics - Upwork
August 5, 2024 - Java programmers usually encounter this infamous pointer exception when they forget to initialize a variable (because null is the default value for uninitialized reference variables).
🌐
GeeksforGeeks
geeksforgeeks.org › java › interesting-facts-about-null-in-java
Interesting facts about null in Java - GeeksforGeeks
September 3, 2024 - In Java, null is also used to indicate that a method does not return any value. This is known as a "void" return type.
🌐
Coderanch
coderanch.com › t › 417559 › java › return-null
can we return null? (Java in General forum at Coderanch)
Since, the pre-existing return statements return the appropriate values local to 'if' loops, 'return null' is added as per the java specifications - considering a situation if your control never enters the 'if' condition; since the return type of your method is Image (a subclass of the Almighty ...
🌐
KapreSoft
kapresoft.com › java › 2023 › 12 › 10 › java-pitfalls-of-returning-null.html
Java • Pitfalls of Returning Null | KapreSoft
December 10, 2023 - In Java, the intention behind returning null is often to indicate an absence of a value or an undefined state. However, this practice can be misleading, as it does not explicitly convey the reason for the absence of a value.
🌐
Coderanch
coderanch.com › t › 688734 › java › null
what does null mean? (Beginning Java forum at Coderanch)
In Java, null is a "placeholder" value that - as so many before me have noted - means that the object reference in question doesn't actually have a value. Void, isn't null, but it does mean nothing. In the sense that a function that "returns" void doesn't return any value, not even null.
Find elsewhere
🌐
Javapractices
javapractices.com › topic › TopicAction.do
Java Practices->Return Optional not null
The problem with returning null is that the caller is not forced into handling the null case.
Top answer
1 of 4
11

null is actually not instanceof anything!

The instanceof operator from the Java Language Specification (§15.20.2):

At run time, the result of the instanceof operator is true if the value of the RelationalExpression is not null and the reference could be cast (§15.16) to the ReferenceType without raising a ClassCastException. Otherwise the result is false.

4.1. The Kinds of Types and Values

There are two kinds of types in the Java programming language: primitive types (§4.2) and reference types (§4.3). There are, correspondingly, two kinds of data values that can be stored in variables, passed as arguments, returned by methods, and operated on: primitive values (§4.2) and reference values (§4.3).

Type: PrimitiveType ReferenceType There is also a special null type, the type of the expression null (§3.10.7, §15.8.1), which has no name.

Because the null type has no name, it is impossible to declare a variable of the null type or to cast to the null type.

The null reference is the only possible value of an expression of null type.

The null reference can always undergo a widening reference conversion to any reference type.

In practice, the programmer can ignore the null type and just pretend that null is merely a special literal that can be of any reference type.

2 of 4
10

Formally, null is a singleton member of the null type, which is defined to be the subtype of every other Java type.

null is a reference type and its value is the only reference value which doesn't refer to any object. Therefore there is no representation of null in memory. The binary value of a reference-typed variable whose value is null is simply zero (all zero bits). Even though this is not explicitly specified, it follows from the general initialization semantics of objects and any other value would cause major problems to an implementation.

🌐
JanBask Training
janbasktraining.com › community › java › how-to-return-null-in-java
How to return null in java? | JanBask Training Community
October 6, 2022 - In all the code I write, I avoid returning null from a function. I read that in Clean Code. The problem with using null is that the person using the interface doesn't know if null is a possible outcome, and whether they have to check for it, because there's no not null reference type.
🌐
Medium
elizarov.medium.com › null-is-your-friend-not-a-mistake-b63ff1751dd5
Null is your friend, not a mistake | by Roman Elizarov | Medium
March 2, 2019 - But who would ever write code like that? Not only list documentation clearly states that it returns null when directory is missing, but modern IDEs flag this particular code with a warning right away. However, people do these kind of mistakes all the time when programming in Java.
🌐
Chris Shennan
chrisshennan.com › blog › return-null-or-throw-exception-best-practice
Return null or Throw Exception - Best Practice? | Chris Shennan
Returning `null` is the programmatic equivalent of "It's broken". Use exceptions to give context and allow you to tailor your error handling.
🌐
Reddit
reddit.com › r/softwareengineering › don’t return null
r/SoftwareEngineering on Reddit: Don’t return NULL
March 13, 2024 -

I’m planning on delivering a tech talk to my team on the pitfalls of explicitly returning nulls in production code, as opposed to using optionals where the language supports it or throwing exceptions when the value is expected to be present.

To make sure I’m not presenting an overly biased view, and to avoid getting blind-sided if someone raises a point I hadn’t considered, I want to hear examples of times you would actually prefer to explicitly return null.

Edit: Since some were curious and I neglected to specify, our team works predominantly in Java so we do have the Optional interface available to us. I have also worked with Go a bit and tbf I did like the ability to have multiple return values in the case of errors etc. I also don’t mind how Swift/Kotlin handle optionals and unwrapping them, I believe they handle it in a similar way.

🌐
Coderanch
coderanch.com › t › 376140 › java › method-return-null-anytime
should a method return null anytime? (Java in General forum at Coderanch)
Throwing an exception instead of a null means that the contract of the method is broken. Returning a null may mean something in your application.
Top answer
1 of 1
1

In Java, null is only a valid value for reference types. It cannot represent a primitive type such as int. Here are some alternatives to consider:

  1. If you are using Java 8 or later, and are able to change the return type of the method you could use the OptionalInt type to represent an int value that may or may not be present. In that case, you would return OptionalInt.empty() in the case that there is no int value to return, and OptionalInt.of(x) to return an int x. Note that the caller will need to unwrap the int value (if it is present) using one of the other methods available on that class. This approach is often preferred for new code, as it makes the intention and usage very clear.
  2. If you are using an older Java version, another possibility is to change the return type to Integer. This is a wrapper class for int values that does allow for null to be returned. In addition, Java's auto-unboxing rules allow it to be used in contexts where an int value is expected, when the value is not null. However, if a null value is unboxed to an int value, it will result in a NullPointerException, so it is important to check for null before performing operations that would result in unboxing.
  3. If you need to use the int return type, it is common to use a sentinal value to represent an abnormal return. For example, if the normal return values for the method are all non-negative integers, you could use a value such as -1 to represent an absent return value. This is commonly used in older JDK methods such as String.indexOf().
  4. In some cases, it makes sense to throw an Exception when no valid value can be returned. It's only a good idea to use this approach for truly exceptional circumstances, as the runtime cost for throwing exceptions is much higher than normal method returns, and the flow of control can make the code harder to understand.
Top answer
1 of 3
5

The dilemma

If a variable with null value gets used in your program causing a NullPointerException, this is clearly a situation in your program which you did not expect. You must ask yourself the question: "Did I not expect it because I didn't take into consideration the possibility of a null value or did I assume the value could never be null here?"

If the answer is the latter, the problem isn't because you didn't handle the null value. The problem happened earlier, and you're only seeing the consequence of that error on the particular line it's used. In this case, simply adding a if (variable != null) isn't going to cut it. You'll wind up skipping lines you were supposed to execute because the variable was null, and you'll ultimately hit a line further on where you again assumed it wouldn't be null.

When null should be used

As a general rule, return null only when "absent" is a possible return value. In other words, your data layer may search for a record with a specific id. If that record isn't found, you can either throw an exception or simply return null. You may do either, but I prefer not to throw exceptions in situations where the strong possibility exists. So you return null instead of a value.

The caller of this method, presumably written by you, knows the possibility exists that the record may not exist and checks for null accordingly. There is nothing wrong with this in this case, though you should handle this possibility as soon as possible as otherwise everywhere in your program you will need to deal with the possibility of a null value.

Conclusion

In other words, treat null as a legitimate value, but deal with it immediately rather than wait. Ideally in your program, you should ever only have to check if it is null once in your program and only in the place where such a null value is handled.

For every value you expect to be non-null, you need not add a check. If it is null, accept that there is an error in your program when it was instantiated. In essence, favor fail fast over fail safe.

2 of 3
8

Deciding whether or not null is a allowed as an object value is a decision that you must make consciously for your project.

You don't have to accept a language construct just because it exists; in fact, it is often better to enforce a strict rule against any nullvalues in the entire project. If you do this, you don't need checks; if a NullPointerException ever happens, that automatically means that there is a defect in your code, and it doesn't matter whether this is signalled by a NPE or by some other sanity check mechanism.

If you can't do this, for instance because you have to interoperate with other libraries that allow null, then you do have to check for it. Even then it makes sense to keep the areas of code where null is possible small if possible. The larger the project, the more sense it makes to define an entire "anti-corruption layer" with the only purpose of preserving stricter value guarantees than is possible elsewhere.