A keyword used in Java to indicate a method does not return a value. It is not
used to indicate a method requires no parameters. Constructors
don't use the void keyword even though they don't
return an object.
Void also refers generically to the various flavours
of hollow Strings, namely: blank (i.e x.length()
!= 0 && x.trim().length() == 0, e.g. " "),
empty (i.e. x.length() == 0,
e.g. "") and null
(i.e. x == null). One of the most common sources of
error in Java programs comes from confusing the three different flavours of void
strings. Java code often has a maintenance timebomb ticking in it in the form of
inconsistent representation of void strings and objects. It is unwise to just
let NullPointerException find your problems for you.
The problem may surface many kilometers from the true source of the problem.
There will always be one more bug. It is better to decide on your canonical void
representation and be fanatically rigid about it.
Which void representation should you use?
-
null is fast to test for, e.g. if (
it == null ),
however, you can't run any methods on it. e.g anull.
equals( somethingElse)
will generate a NullPointerException.
-
"" will work as a parameter to most
methods expecting a String.
If you don't use a canonical representation and consistent checking for the
various void forms you will have two classes of bug:
-
Void Strings mistakenly treated as if they were non-void. The effect can be
indirect and very hard to track down. e.g. You may test for the presence of A
and if it exists do some operation on B.
-
Non-void Strings are mistakenly treated as if they were void. Data just
disappear or are ignored.
These bugs can be a bitch to track down because the variant voids or void itself
are often rare for many data fields. It may require a particular improbable
constellation of data for the bug to surface.
There are two plausible canonical representations for void namely null
and empty (""). Normally you combine either
of them with canthappen. The four ways you might
represent void Strings are:
-
canthappen
Check for all forms of void parameters and throw an IllegalArgumentException
or NullPointerException if Java won't throw one all by
itself soon. It is far easier to prevent bad data (i.e. inconsistent void
representations) getting into your objects and databases that to deal with it
once it gets in. You might wrap this code in if (debugging)
so it can be turned off for production speed. Unfortunately Java has no design-by-contract
features to do this more elegantly. You can catch these with a neverNull
method.
-
null
Make sure all void inputs are converted to null using a possiblyNull
method.
-
empty
Make sure all void inputs are converted to "" using a possiblyEmpty
method.
-
blank
Not recommended.
You are just asking for trouble if you use a variety of void representations.
The code may be clear to you, but will drive people who come after you
maintaining the code crazy.
In a similar way you can get into trouble returning null
instead of an empty Collection. One convention,
used by File.list, is to return an empty array or Collection
for no elements, and null to represent the result
of an invalid request.
Note to C programmers
There are a few differences between C and Java that may confuse you.
-
Java Strings don't have a terminating 0 byte. They
don't have a terminating 0 character either. Java Strings
are 16-bit characters. Instead, they have a hidden 32-bit count field to track
how long they are.
-
NULL in C is just a synonym for 0. null
in Java is a magic value that can be assigned to pointers/references to say they
don't currently point to anything. Instance and static
references are automatically initialised to null
for you in Java. Usually this value is represented by 0 at the hardware level,
but there is no way you could find out just by writing a Java program.
-
In C, there is a difference between NULL, and a
string consisting only of a single 0. In Java, the equivalents are null
and "" which makes a similar distinction.