Java has four different “kinds” of types. Up until Tiger, it had these three:
- Primitive types: longs, shorts, booleans, ints, outs, whatever. They map more or less to machine types.
- Classes, which are the primary mechanism for extending the language.
- Arrays, which are this weird hybrid type that was introduced to make it easy to port C and C++ code to Java. But you can’t make arrays immutable, and you can’t subclass them, and there’s only modest syntactic support for them, and reflecting on them is painful.
The problem, of course, with having different types of types is that all of the code you write, now and forever, has to be prepared to deal with each type-type differently. So you get interfaces like this lovely one. Scroll down to the Method Summary, and looky looky, there are 76 actual methods in the class, but only 10 distinct pieces of functionality.
Just to make things worse, Java 5 added a new kind of type, called an enum. They’re sort of like C enumerations, but they can also have methods. Which makes them sort of like Java classes, but you can’t instantiate them, and you can’t have one enum type inherit from another enum type, so you can’t have polymorphic methods, nor can you declare an enumeration heirarchy. So they’re not really like classes at all.
— Steve Yegge, The Next Big Thing (lightly edited for brevity).