Many object-oriented languages follow the ALGOL W example and allow null references. Tony Hoare invented the concept in 1965 and since then has called it his "[my] billion dollar mistake".
The follwoing example is destilled from assignment solutions for the lecture Computergrafik Grundlagen.
The Shape
interface states that a method intersect()
exists that takes an object of type Ray
as an argument and returns an object of type Hit
.
class Hit {double t;}
class Ray {}
interface Shape {
Hit intersect(Ray r);
}
Concrete instances of Shape
implement the intersection method differently. For example the Sphere
class implements it like this:
class Sphere implements Shape{
public Hit intersect(Ray r) {
if (/* some involved test */)
return new Hit(/* some value for t */);
else
return null;
}
}
Client code of the Shape
interface has to be prepared, that instead of a valid Hit
object, null
is returned to signal the absence of a hit. The interface however, does not explicitly state that this might happen.
A NullPointerException
is arguably the most frequently encountered exception in any Java program.
class Sphere implements Shape{
public Hit intersect(Ray r) {
return null;
}
}
Ray ray = new Ray();
Sphere sphere = new Sphere();
Hit hit = sphere.intersect(ray);
if (hit != null)
System.out.println(hit.t);
else
System.out.println("No hit");
No hit
A better solution is to use the Optional
type that explicitly says there might be no value and forces the programmer to check before using a value.
interface ShapeO {
Optional<Hit> intersect(Ray r);
}
class SphereO implements ShapeO {
public Optional<Hit> intersect(Ray r) {
return Optional.empty();
}
}
Ray ray = new Ray();
SphereO sphere = new SphereO();
Optional<Hit> hit = sphere.intersect(ray);
if (hit != null)
System.out.println(hit.t);
else
System.out.println("No hit");