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 warts. 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.
Of course it's easy for us book writers to sit in our ivory towers and make fun of a lot of people's hard work, and many of these decisions were likely made deliberately to help market the language as a version of C (it isn't). That definitely improved it's early acceptance and so was necessary for its survival. Pity though. Perhaps the next major language will fix these language bugs.
intvalues are only 32 bits so we can't do everything needing whole numbers with them (we can't count time in milliseconds with
ints!). we can use
longin its place but can't use
longs to access arrays, or to control switch statements, or to do thread-safe atomic operations. the overdependence on
ints will lead to long-term problems.
doubledivision. 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 "
multiple bitwise operators are easy to confuse with shortcutted
too much C history: pointless typing shortcuts like
/=. the ternary operator, multiple initializations in
fors, and other excesses.
poor (almost no) package support.
ifstatements should have a
then. easier to read than brackets.
objects shouldn't be able to access class variables or execute class methods.
variables should be
privateby 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 "
Java breaks its own naming rules for
Hashtable, and array.
many inconsistencies in even the core API. For example, the variable
lengthin arrays, the variable
Polygon, the method
String, and the method
Vector. then there's the method
Thread, not to mention
Listand so on.
the Java API writers committed many style crimes with non-thread-safe publically accessible non-
Point, 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 like
NullPointerException. 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.