开发者

Anomalies in Java platform libraries

Sometimes I look into Java platform libraries for inspiration. There are plenty of good design solutions there, see this question for example. However there are anomalies as well that should not be emulated. Some of them are given in the book Effective Java, Second Edition by Joshua Bloch, for example constant interfaces such as java.io.ObjectStreamConstants or the behaviour of the equals method i开发者_JS百科n java.net.URL. What other examples of such anomalies in the Java platform libraries do you know? Please give as many as possible.


The close() method declaring to throw IOException which probably no sane implementation throws. And if ever thrown, it is very impossible to write a finally block that handle that correctly.

java.util.Enumeration and java.util.Iterator are essentially the same thing.

java.util.Vector, java.util.Hashtable and java.util.Dictionary should be deprecated.

Object.clone() and the Cloneable interface are horrible and haves a lot of problems.

javax.swing.table.DefaultTableModel is evil.

java.io.Serializable defines a strange special contract with optional private readObject() and writeObject() methods.

java.util.Observable should never be used.

The finalize() method is an anomaly and should be avoided as much as possible.

All the date/time API is very badly designed. java.util.Date ended having almost all of it's methods deprecated. java.util.Calendar has an horrible get(int) and set(int, int) method taking an integer identifying the field, instead of proper defined getters and setters. java.sql.Date and java.sql.Timestamp extends java.util.Date in the worst manner possible: The documentation explicitly tell that it extends but should not be considered a IS-A relationship (which is really bad, since extension purpose is to define an IS-A relationship). Further, some methods of java.sql.Date overriden form java.util.Date throws exceptions breaking the superclass contract and failing Liskov Substitution Principle (which the authors probably did not cared too much, since they did not wanted an IS-A relationship).


The lack of a uniform construct for iterating collections, arrays and enumerations.


On a higher level than what you maybe meant in your question, things like the date and time API (mainly classes java.util.Date and java.util.Calendar) are not great in the standard library. One of the mistakes is that these classes are mutable. The Joda Time library is much better designed.

Also, the XML API is cumbersome and hard to use, and strangely does not contain a clear way to convert a DOM tree (an org.w3c.dom.Document) into a string or text that can be written to for example a file. You can do it with an XSL transform that does nothing (like this example) but it is not very intuitive. Because of this poor design there are a lot of alternative XML libraries that are popular (for example JDOM, XOM, XStream etc.).

Another thing in the XML API that annoys me is that it doesn't use the standard collection classes. For example, why is there this strange org.w3c.dom.NodeList interface - why not use a standard java.util.List<Node>? And why does NodeList have those methods getLength() and item(int index) method that are so inconsistently named compared to the standard collection classes? Why does the XML API not support standard iterators?

The collection of standard platform APIs has grown over time so it's now a large and inconsistent set of stuff, which cannot be changed without breaking backwards compatibility.


    int stringLength = string.length();
    int listLength = list.size();
    int arrayLength = array.length;

How inconsistent! All from Java 1.2 or earlier...


  • Primitives.
  • Covariance of Java arrays is simply an error in the Java spec.
  • The Date/Calendar API, as others have mentioned, is a shocker.
  • Circular dependencies throughout the APIs. Did you know that java.lang depends on java.util, java.net, and java.io? And of course since 1.4, java.io depends on java.nio and vice versa.
  • Neither AWT nor Swing should have been included in the core JRE. It makes no sense in pure-server side environment, or for people who want to use alternative GUI libraries like SWT or JavaFX. Instead, Java should have had a proper module system from the outset, and made Swing available as a separate module for those who actually want it.
  • Take a look at the JavaDoc for XMLOutputFactory.newInstance(String, ClassLoader) from the StAX API. Yup, it returns the wrong type of object. This error is in the JSR Final Specification for StAX! And since StAX has been included in the JRE since Java 6, you can't just update to a non-broken version. Again, if only Java would stop rolling broken shit into the JRE...
  • I'll stop there. I could probably go on all day...


I have always wondered why java.util.Hashtable is not named java.util.HashTable. All other Java classes in standard libraries are capitalized (eg. LinkedList, HashMap and so on).

Another strange thing for me was the behaviour of StringBuffer equals() method.

StringBuffer s1 = new StringBuffer("Test");
StringBuffer s2 = new StringBuffer("Test");
System.out.println(s1.equals(s2));

will print false. It is because equals() method does not compare Strings contained in StringBuffer objects, but objects (it will return true only if you compare s1 with s1).


Object.clone() and the Cloneable interface

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜