I’ve seen this question but have a few more questions about the usage of the assert
keyword. I was debating with a few other coders about using assert
. For this use case, there was a method that can return null if certain prerequisites are met. The code I wrote calls the method, then asserts it doesn’t return null, and continues to use the returned object.
Example:
class CustomObject { private Object object; @Nullable public Object getObject() { return (object == null) ? generateObject() : object; } }
Now imagine I use it like this:
public void useObject(CustomObject customObject) { object = customObject.getObject(); assert object != null; // Do stuff using object, which would throw a NPE if object is null. }
I was told I should remove the assert
, that they should never be used in production code, only be used in testing. Is that true?
Advertisement
Answer
Use Objects.requireNonNull(Object)
for that.
Checks that the specified object reference is not null. This method is designed primarily for doing parameter validation in methods and constructors, […]
In your case that would be:
public void useObject(CustomObject customObject) { object = customObject.getObject(); Objects.requireNonNull(object); // throws NPE if object is null // do stuff with object }
This function is made for what you want to do: explicitly mark what is not to be null
. The benefit is that you find null
-values right where they should not occur. You will have less troubles debugging problems caused by null
s that are passed somewhere where they shouldn’t be.
Another benefit is the flexibility when using this function in contrast to assert
. While assert
is a keyword for checking a boolean value, Objects.requireNonNull(Object)
is a function and can be embedded in code much easier.
Foo foo = Objects.requireNonNull(service.fetchFoo()); // you cannot write it in one line. Bar bar = service.fetchBar(); assert bar != null;
service.foo(Objects.requireNonNull(service.getBar())); // you cannot write it in one line. Bar bar = service.getBar(); assert bar != null; service.foo(bar);
Keep in mind that Objects.requireNonNull(Object)
is only for null
-checking while assert
is for general assertions. So assert
has different purposes: primarily testing. It has to be enabled, so you can enable it for testing and disable it in production. Use it to seperate testing-only-tests from tests, or rather checks, that are meant for production-code too.