Java Design Flaws

Flaw concerning this page: below it says "describe (in the linked page) why the design flaw is actually a problem. Please keep the list clean by removing entries that have neither votes nor a linked page.". Well, I'd like to add The Lclass (which I did not write, incidentally) to this page, but the rule says that I can't without doing extra work. I should just be able to link The Lclass, and others could later add the votes, add a better description of the problem to The Lclass page, and also I should be able to list a Java problem that does not yet have its own page -- unlinked Wiki Words are part of the Wiki Way. But I sure as hell am not going to get into an edit war about this.

"Removing entries that have neither votes nor a linked page" means that if an entry has either votes or a linked page, it's fair game. Not a flaw, and add away.


Why ?

This page describes design flaws in Java. In a manner more constructive than a Language Pissing Match, we ponder how the language could be made better at reasonable conceptual or implementation cost, and hopefully glean applicable insights along the way.

What goes in this List?

In short, design flaws. Those which affect the language itself, or the Core API classes which no programmer could possibly avoid being aware of - collections, Object, Thread... We don't want a list of bugs in Sun's Java implementation. If it can be easily fixed, it may not go on the list either. If it can't be fixed without making Java a totally different language, it's not really interesting either. What we want here is a list of serious mistakes in Java, so that we can avoid them in the future.

Please keep the list ordered according to the number of votes.

Please choose titles such that a person who does not know what you are talking about gets the idea. Furthermore, describe (in the linked page) why the design flaw is actually a problem. Please keep the list clean by removing entries that have neither votes nor a linked page.

Messy Exception Hierarchy . . . . . . . . . . . . . . . . votes:
16 (antivote: 0)

Checked Exceptions Are Of Dubious Value . . . . . . . . . . votes:
13 (antivote: 11)

No Real Java Meta Model . . . . . . . . . . . . . . . . . . votes:
14 (antivote: 1)

Cloneable Does Not Implement Clone . . . . . . . . . . . . votes:
9 (antivote: 4)

Java Arrays Should Be First Class Objects . . . . . . . . . . votes:
8 (antivote: 1)

Every Object Isa Monitor . . . . . . . . . . . . . . . . . votes:
8 (antivote: 2)

Java Primitive Types Should Be Objects . . . . . . . . . . . votes:
8 (antivote: 3)

Unmodifiable List Is Stupid And It Breaks Lsp . . . . . . . . votes:
5 (antivote: 2)

Java Exceptions Should Be Interfaces . . . . . . . . . . . votes:
4 (antivote: 4)

Java Object Overhead Is Ridiculous. . . . . . . . . . . . . votes:
4 (antivote: 3)

Java Arrays Break Type Safety . . . . . . . . . . . . . . . votes:
3 (antivote: 4) (not fixed in JDK 1.5 - generics ea 2.0 only)

Java Io Classes Are Impossible To Understand. . . . . . . . . votes:
3 (antivote: 5)

Java Exec Isa Total Mess . . . . . . . . . . . . . . . . . votes:
4 (antivote: 1)

Java Static Classes Isa Total Mess . . . . . . . . . . . . . votes:
3 (antivote: 2)

No Multiple Dispatch In Java. . . . . . . . . . . . . . . . votes:
4 (antivote: 3)

Finalize Instead Of Proper Destructor . . . . . . . . . . . votes:
3 (antivote: 9)

Java Old Syntax . . . . . . . . . . . . . . . . . . . . . votes:
2 (antivote: 1)

Java Document Model Breaks Encapsulation . . . . . . . . . votes:
2 (antivote: 0)

Static Methods Non Polymorphic . . . . . . . . . . . . . . votes:
2 (antivote: 1)

Java Floating Point . . . . . . . . . . . . . . . . . . . votes:
1 (antivote: 0)

Java Lacks Language Support For Lists . . . . . . . . . . . votes:
0 (antivote: 0)

Java Interfaces Cannot Specify Constructors . . . . . . . . votes:
1 (antivote: 3)

Java Autoboxing Is Not . . . . . . . . . . . . . . . . . . votes:
1 (antivote: 0)

Java Date Class Is Not Immutable . . . . . . . . . . . . . . votes:
1 (antivote: 0)

(Note to everyone else who edits this file: the list above needs to remain monospaced.)


Items previously above that were accurate critiques, but were fixed in the Java Language, and therefore removed from the above list:

No Covariant Return Types . . . . . . . . . . . . . . . . votes:
15 (antivote: 0) (fixed in JDK 1.5)

Java Lost Enumerated Types . . . . . . . . . . . . . . . . votes:
7 (antivote: 3) (fixed in JDK 1.5)

Choice Operator Does Not Consider Inheritance . . . . . . . votes:
5 (antivote: 2) (fixed in JDK 1.5)

Iterator Semantics Are Wrong . . . . . . . . . . . . . . . votes:
3 (antivote: 2) (fixed in JDK 1.5)


Items previously above that were not accurate critiques, and therefore were removed from the above list:

Java Empty List Is Broken . . . . . . . . . . . . . . . . . votes:
3 (antivote: 1) (it seems this is simply false)

Sets Break Collection Contract . . . . . . . . . . . . . . votes:
2 (antivote: 6) (while the claim has some merit, it probably shouldn't be on this list)


A link to this page was posted on comp.lang.java.advocacy by Thomas Holenstein. Given the number of anti-Java bigots that hang out there, I don't expect any reasoned debate or unbiased voting to ensue.


Is it me, or do a lot of these complaints boil down to either "Java Isn't Smalltalk" or "Java Isn't C"? The "Choice Operator" (?:) one, especially, is something that has never bothered me, and that I probably would never have even encountered. But I can see how it would loom large for someone who fell in love with ?: while coding lots of C.

Would that all software had such severe flaws. --George Paci

I think that the items with the most votes (and the choice operator item) highlight conceptual inconsistencies within the language, rather than wishes that Java was more like another language. Issues such as arrays breaking type safety, operators not working with Java's inheritance model, lack of covariant return types, or reservations about exception handling come from a desire for Java to have as few "warts" as possible. -- Anonymous Donor

Yes, many of these complaints are indeed saying "Java Isn't Smalltalk/C/C++/Lisp." However, it's important to note that Java was designed to be an 'ideal' combination of these languages. The complaints above, under this light, are indeed flaws; they are areas where the designers of the Java Language placed a very different priority on a certain feature than the developers who ended up using the language would have. No, many of them are not flaws in the sense of contradictions or defects; however, they are flaws in that the language did not live up fully to its design goals. Of course, on another note, I'd say that Java has done a better job of living up to its goals than any other language, with the possible exception of Scheme Language. -- Adam Berger

That ("better job of living up to its goals than any other language") seems like a strong statement, unless you mean it in Paul Graham's take on Java ("intended to be a language for the masses" / "and therefore not desirable for smart people"), which I doubt you meant. :-) But obviously you have some specifics in mind; share? -- Doug Merritt

My company (Component Software Corporation) and I participated in the creation of Java, we were there when it was born, and I can tell you that the original design goal was to provide Smalltalk functionality with C-like syntax. Two dimensions of that goal are relevant to this page: Java-the-environment and Java-the-language. Regarding Java-the-language, the first choice was Cee Plus Plus. When we demonstrated that Cee Plus Plus semantics precluded making Java-the-environment be sufficiently like Smalltalk, the next choice was Objective Cee, which we extended with a type system and for which we built and delivered to Sun a Virtual Machine. That Virtual Machine became the early Java Virtual Machine. Java-the-language was syntactic sugar that was semantically equivalent to our extended Objective Cee. All of this is to say that the complaint that "Java isn't Smalltalk" is, in fact, a historically accurate starting point for identifying its design flaws. It is perfectly reasonable, in that context, to also discuss Smalltalk Design Flaws. -- Tom Stambaugh



I wonder if we would better use a Wiki Weighted Vote or a Wiki Multiple Vote. Now, recent entries don't have a chance to get to the front of the list. What do you think?


How about:

New items to vote on:


Does weak expressiveness count? A line or two of Haskell, Ocaml, Lisp, or Scheme can often do the work of ten lines of Java (which is up there with other painful languages, like C/C++). (Java Lacks Real Macros, Java Lacks Data Description, Java Lacks Symmetry)

Java is "protection-oriented" language in that it uses verbosity to help the compiler verify things fit the programmer's or library builder's intent. Generally there is a trade-off between verbosity and protection. However, there are some annoying features that seem like they could have been done shorter without losing protection. Examples:

bigClassName foo = new bigClassName(x);

This seems redundant and is a common pattern. Although it's possible the "type" can be different than the class, if it's not, then it should somehow default to being the same:

foo = new bigClassName(x); // suggestion 1:
type assumed to be "bigClassName" if omitted.

foo = new bigClassName(x); // suggestion 2:
wildcard char to indicate "bigClassName"

bigClassName foo = new(x); // suggestion 3:
"new" constructor shortcut. Full version still allowed if wanted.

bigClassName(x) foo; // suggestion 4:
combo type-and-constructor

And:

System.out.println(x); // Surely they could have built a short-cut

[Indeed. For this, you want C#'s 'var' keyword or Scala's 'val'. It's somewhat surprising that it wasn't introduced in Java 8, but it wasn't. As for System.out.println(), it's almost never used in production code unless you create command-line utilities, and then it's trivial to create your own short-cut like PrintStream p = System.out; p.println("zot"); p.print("foop"); ... etc.]

You are right about production systems, but it bloats up examples and debugging code.

[You can fix it, like I did. See above re PrintStream p = System.out;]

But one has to repeat it for each class, and it varies per author. A commonly-recognized and global shortcut would be the ideal.

{I'm not a Java expert, but is there some reason you can't do?}

import java.lang.System.out;

out.println(x);

[It can't be done because System is a class and 'out' is a public member of System. You can import classes and packages of classes, but not members of classes, and all class members must be explicitly qualified by a class name (if and only if the member is static) or a reference to a class instance.]


See original on c2.com