Fortran's tragic fate has been its wide acceptance, mentally chaining thousands and thousands of programmers to our past mistakes.
Java is a beauteous language, but it's still a human creation. It has flaws. Some are thanks to the limitations of today's input devices, some are in the name of efficiency, some are sheer oversight, and some are deliberate marketing decisions. Here are some of them.
Perhaps the next major language will fix these language bugs.int
values are only 32 bits so we can't do everything needing whole numbers with them (we can't count time in milliseconds withint
s!). we can uselong
in its place but can't uselong
s to access arrays, or to control switch statements, or to do thread-safe atomic operations. the overdependence onint
s will lead to long-term problems.
int
division overloadsdouble
division. this causes confusion about which meaning is which, which can lead to serious and subtle errors.
no overflow or underflow warnings.
thread sleep time expressible only in milliseconds
starting all indexes at 0 instead of 1 causes many fencepost errors
assignment uses "=" instead of say "<-
" or some other unique string. this causes confusion with "==
" equality.
multiple bitwise operators are easy to confuse with shortcuttedboolean
operators inboolean
expressions.
too much C history: pointless typing shortcuts like%=
and/=
. the ternary operator, multiple initializations infor
s, and other excesses.
poor (almost no) package support.
if
statements should have athen
. easier to read than brackets.
objects shouldn't be able to access class variables or execute class methods.
variables should beprivate
by default, not package.
the horror that is the awt.
the horror that is javadoc.
no special storage type for constants.
there is no separate subclass access modifier. mixing subclass access and package access into one confuses the contracts for both. java used to support a "private protected
" modifier for subclass access only (not confused with package access) but did away with it. it caused too much confusion. it wouldn't have if it was called, say, "family
" or "children"
instead.
Java breaks its own naming rules forColor
constants, theinstanceof
operator, and allprintln
methods. and array.length
.
many inconsistencies in even the core API. For example, the variablelength
in arrays, the variablenpoints
inPolygon
, the methodlength()
inString
, and the methodsize()
inVector
. then there's the methodactiveCount()
inThread
, not to mentioncountMenus()
inMenuBar
,countComponents()
inContainer
andcountItems()
inList
and so on.
the Java API writers committed many style crimes with non-thread-safe publically accessible non-final
variables (x
andy
in classPoint
, for example)
constructors should instead be called initializers.
conflating the dot in package names with the dot operator for object references confuses both.
the separation into primitives and object types is artificial and leads to special rules for each in arrays and method parameter passing.
archaic names that break the metaphor likeNullPointerException
. Java supposedly has no pointers.
Java missed the purity boat in a number of ways, the biggest of which is probably no interpreter support for assertions and weak support of packages, but more generally the whole idea of programming by contracts would be wonderful to have in a portable language. we should be able to say that this class of objects behaves this way with that class of objects, but this other way with that other class of objects. in short, we should be able to specify interpreter-supported contracts between classes of things. this becomes especially important when we start to move away from simple things like modeling trees and plants and human artifacts like cars and blenders and try to model more complex things like nation states, corporations, ideas, or people.