Conrad Weisert
1 October 2009
©2009, Information Disciplines, Inc.
This article may be copied and distributed freely as long as the copyright credit is included
The title of this article will be jarring to some Java zealots. When Java was new, we kept hearing presentations and reading articles proclaiming, on the contrary, that
"In Java, everything is an object."
Q: Which statement is true?
A: They're both absurdly false.
The older assertion was not only false but also insulting to the intelligence of a knowledgeable programmer. Typical non-trivial application programs in Java contain independent functions, i.e. functions that are not methods invoked through an object.
What the early Java promoters meant was only that every Java function and every
Java data declaration has to be packaged inside some Java
class
definition. Such
pseudo classes are merely packaging artifices. They have
nothing at all to do with the object
paradigm. In fact, students who learn Java as their
first programming language are often confused about the real purpose of classes, and
they require patient clarifying explanation.
In my work I see lots of source code. One phenomenon that used to surprise me
and no longer does is that many, perhaps most, Java programs that perform numerical
calculations work with floating-point (double
)
numbers, as if they were coding in 1959 Fortran. They get no benefit from
automatic checking of units integrity or range limitation. The source code doesn't
make clear what the
data item actually is, except through its name and accompanying commentary.
One obvious reason for Java programmers' avoiding objects for numeric data
is Java's prohibition of operator overloading.
If you use untyped floating-point numbers you get to use familiar mathematical
expression syntax, while if you use numeric objects
you're stuck with clumsy nested function notation or, worse, awkward cheating with
getValue()
and
setValue()
.
But that's not the worst reason. Take a look at Java's standard
Math
pseudoclass.
Math
contains much the same list of
functions that were provided in the built-in libraries of Fortran, PL/I, Pascal and
other procedural languages. In particular it provides these trigonometric functions:
public static double sin(double a) |
public static double asin(double a) |
public static double cos(double a) |
public static double acos(double a) |
public static double tan(double a) |
public static double atan(double a) public static double atan2(double a, double b) |
Those old-fashioned functions are an unsubtle invitation to the programmer not to
define or use an Angle
class. Java's designers
very clearly expected user-programmers to use Java's primitive floating-point numbers
instead of objects.
Java's designers had an opportunity to foster the object paradigm when they introduced
the language. Including an Angle
class in
the standard library could have led to the obvious instance and class functions:
public double sin() |
public static Angle arcsin(double x) |
public double cos() |
public static Angle arccos(double x) |
public double tan() |
public static Angle arctan(double x) public static Angle arctan(double y, double x) |
If the Java libraries had provided an Angle
class, no user would have been forced to use it. The
Math
pseudoclass could still have provided
the floating-point functions as an alternative. Or (ugly)
Angle
could have provided
getValue()
and
setValue()
accessor functions.
Peter van der Linden's superb book suggests
that a naive programmer might try to extend Math
in order to override the standard trigonometric functions that use radians as
the unit of measure with an equivalent set that uses degrees. Of course, that can't be done,
since extending a pseudoclass makes no sense, but it's disappointing that van der Linden
didn't mention that the existing implementation is badly flawed. One of the main
advantages of an Angle
class is that
user programs needn't know whether the internal (hidden) representation is in
degrees or radians. See Stamp Out Multiple
Object Representations for further discussion.
Of course Angle
class is not the
only example of the widespread avoidance of objects by Java programmers, but
the Math
library's blatant undermining
of objects makes it especially conspicuous. A wise Java programmer will
question any non-trivial reliance on the built-in primitive data types,
especially numeric items that have a unit of measure and a well defined repertoire
of behavior. Failure to exploit OOP when programming in an object-oriented language
is indeed a serious design flaw, even though the program may "work"..
The IDI library contains an Angle class, which is undergoing revision to be consistent with the hashing controversy. Check back later for a revised version.
Return to technical articles
Return to Java topics
Return to IDI home page
Last Modified, 1 October 2009