share
Stack OverflowWhat is your "favourite" Java API annoyance?
[+43] [39] flybywire
[2009-11-08 17:18:09]
[ java api ]
[ http://stackoverflow.com/questions/1697215/what-is-your-favourite-java-api-annoyance ] [DELETED]

What is your "favorite" API annoyance or missing feature or misengineered part?

(10) Hey closers, how is this not programming related? - flybywire
I'm pretty sure there was a question asking pretty much the same thing already, can't find it right now 'though ... - Joachim Sauer
(2) @Shog9, Though this may still be a dupe, the question you linked is about the language, not the API. - finnw
(3) Hey flybywire, how is this not subjective? - Ken
(1) @Ken: it's not subjective because it's a community wiki and even though individual response may be subjective (one's "favorite" is subjective) but the answers that gets the more upvotes tend to reflect very-real and very-non-subjective Java annoyances. But anyway here on SO "closers" are on heavy drugs, I'd like to have some of the stuff they're taking. Questions like this one make SO trully great. - SyntaxT3rr0r
[+84] [2009-11-08 17:21:06] BalusC [ACCEPTED]

java.util.Date [1] is one and all epic fail. The Calendar isn't much better. I am really looking toward JSR-310 [2]. Until then Joda Time [3] is a perfect alternative.

Edit: Oh, one more comes to mind: java.sql.Connection, Statement and ResultSet doesn't implement kind of Closeable interface such as Java IO (finally) has [4] since 1.5. You have to write at least three almost the same utility methods to close all of them in a short and proper manner.

[1] http://java.sun.com/javase/6/docs/api/java/util/Date.html
[2] https://jsr-310.dev.java.net/
[3] http://joda-time.sourceforge.net/
[4] http://java.sun.com/javase/6/docs/api/java/io/Closeable.html

+1, a total failure. - Yishai
As annoying as the broken Date API is, it's good to know that that's the worst core API we have to deal with ;-) - Joachim Sauer
Date is essentially just a reimplementaiton of the Unix date structure. Calendar is a bad, bad donation - if I remember correctly - from a failed project. I believe the name was Taglient, but apparently I cannot spell it :) - Thorbjørn Ravn Andersen
(4) sql.Date, sql.Time and sql.Timestamp are also worth mentioning here! Three subclasses of util.Date which have their own overridden logic which makes them completely pointless! While OO is good, not everything should be in its own class... - Esko
Similarly, why does java.net.ServerSocket not implement java.io.Closeable? - Elliot
(2) @Thorbjørn - are you thinking of Taligent ? - Brian Agnew
@Esko: however they do have a point in JDBC: the ability to store a DATE, TIME or TIMESTAMP in the DB in flavor of a Java object using the respective PreparedStatement methods. - BalusC
msmvps.com/blogs/jon_skeet/archive/2009/11/02/… -- "Humanity Epic Fail" (talks about Java Date handling so...) - pst
BalusC: While I'm against magic in my code, that part of JDBC is too convoluted; If I feed a util.Date to DATE field, I would assume only the date is stored just as with TIME and TIMESTAMP. In my opinion the possible field types in JDBC do not justify the need for subclassing Date because it just adds another layer of confusion. One may even accidentally do a ninja cast directly to util.Date and be completely stumped why one isn't getting the proper return value... - Esko
(1) ...and this reflects to ResultSet's accessors too, in some JDBC drivers you can use getDate(), getTime() and getTimestamp() for all the different datetime fields which just makes no sense at all. - Esko
It would be hard to beat java.util.Date. I knew I'd be too late to complain about its design first, but I thought I'd at least be here in time to be the first one to complain about the variety of quirks with respect to JDBC drivers and java.util.Date. Alas, I've been beaten on both counts. - Justin Searls
(1) @Brian Agnew, yes that's the name. Have a look at wapedia.mobi/en/International_Components_for_Unicode (the history part and the prominent word "Calendar"). Sigh. Sigh. Sigh. - Thorbjørn Ravn Andersen
Certainly the biggest pain in the arse with the API, imo. Causing particular problems at the moment on a GWT client-side. - mcm
1
[+72] [2009-11-09 19:30:37] Peter Lawrey

Poor choices for of names are a favourite pet hate.

Classes which extend a class of the same name.

java.sql.Date [1] extends java.util.Date [2]

com.sun.corba.se.spi.orb.ORB extends com.sun.corba.se.org.omg.CORBA.ORB extends org.omg.CORBA_2_3.ORB extends org.omg.CORBA.ORB

Error which is not an error

com.sun.org.apache.xalan.internal.xsltc.compiler.util.TypeCheckError extends Exception

Exception which is not an exception

javax.print.FlavorException which is an interface

Confusing mix of case

com.sun.org.apache.bcel.internal.Constants.ArrayType which implement equals and hashcode but NOT hashCode()

Stupidly long class name

com.sun.java.swing.plaf.nimbus. InternalFrameInternalFrameTitlePaneInternalFrameTitlePaneMaximizeButtonWindowNotFocusedState

The last one I liked so much I wrote a poem

InternalFrame InternalFrame
Title Pane,
Internal Frame 
Title Pane.

Maximize Button Window,
Not Focused State.
[1] http://java.sun.com/javase/6/docs/api/java/sql/Date.html
[2] http://java.sun.com/javase/6/docs/api/java/util/Date.html

(39) The poem made me almost cry (of laughing). - Lluis Martinez
(2) Thanks. It is hard to imagine a human actually chose that name or if it was generated code, didn't think sh!t, I have to fix that. ;) - Peter Lawrey
(8) I thought you just made up that class name until I googled it. Dear god - TheLQ
2
[+67] [2009-11-08 18:57:20] davidsheldon

My favourite is java.net.URL. .equals() and .hashCode() require network access, because of the silly spec that two URLs are equal if their domain names resolve to the same IP. Not only does this mean that putting them into collections is slow and doesn't work when the network has been firewalled out on a customer's site, but it means that two URLs that will serve different content with HTTP/1.1 will return equal.


(13) luckily they fixed that with the URI class - Jorn
(1) Agreed, the URL stuff is very annoying. At the point it starts resolving, it stops being a useful datatype for holding data and actually starts being an annoyance to which you need to find workarounds. Thank god for URI, but its a pity that URL can't be fixed :) - Chris Dennett
Ugh, thanks for sharing. That's one thing I'll look out for. - James Poulson
3
[+27] [2009-11-08 17:40:47] Brian Agnew

SimpleDateFormat [1] is not thread-safe. I mean, how hard can that be to fix ?

[1] http://java.sun.com/j2se/1.4.2/docs/api/java/text/SimpleDateFormat.html

+1: I recall very good that it was one of my first serious programming mistakes when I professionally started with Java a couple of years ago. It was hard to believe my mentor when he told that it was kind of a flaw in the API. - BalusC
I visited a client who had written a custom JAXB marshaller that used this. All went well when they ran single-threaded. A few months later they ran it in a multi-threaded mode, and obviously generated a ton of invalid XML :-( Nice, huh! - Brian Agnew
(11) Thread-safety makes slower... You should only make things thread safe if you need to. - Thorbjørn Ravn Andersen
(18) I think I would be hard pushed to write a date formatter that wasn't thread-safe. I'm not talking about synchronisation. I'm struggling to understand where the shared state comes from. - Brian Agnew
(3) To clarify, if all the state is kept on the stack during the method call, then it's thread-safe without any expensive (or inexpensive) locking. - Brian Agnew
(1) Brian - I found a fix :) joda-time.sourceforge.net/api-release/org/joda/time/format/… - MetroidFan2002
Part of the problem is that you see examples all over the Internet of people storing SimpleDateFormat objects and public static finals. Worse is the fact that, even in multithreaded environments, it will probably work fine most of the time. Usually you find out when your application crosses some threshold of activity. I agree, though; I can't think of any reason why they couldn't be thread-safe. - Robert J. Walker
(1) I worked as a sysadmin for a large website written as a Tomcat application. The application started to crash from time-to-time. I tracked it down to SimpleDateFormat and promptly demanded the team of programmers there, who had littered the code with thread-unsafe calls to SimpleDateFormat, to fix it! - PP.
(3) The shared state in SimpleDateFormat is the Calendar object used to decompose the date/time into its components. - Mark Thornton
(2) @Mark, and that is probably because the Calendar is heavy, heavy, heavy, which leads us back to stackoverflow.com/questions/1697215/… - Thorbjørn Ravn Andersen
4
[+27] [2009-11-08 18:05:20] Dave Ray

There's a String.split() method, but no String.join(). So annoying.

See also "Ten Little Soul Crushing Features of Java" [1]

[1] http://blog.darevay.com/2009/04/ten-little-soul-crushing-features-of-java/

+1: ran into this a couple of time as well. - BalusC
Yea ... but you cannot define a symmetric split/join because (for a start) split takes a regex string as a parameter. - Stephen C
(6) That's not a good excuse. Join could use the regex to randomly generate delimiters :) - Dave Ray
(1) @Stephen C: Who says that join/split need to be symmetric? They should just be close to what the user expects. - Robert Massaioli
5
[+20] [2009-11-08 17:50:37] Adamski

java.util.Stack deserves a special mention for violating Object Oriented Programming 1-0-1:

Stack inherits from Vector but does not obey the "is-a" relationship typical of inheritance relationships. This (mis)implementation makes it possible to perform "illegal" operations on the stack such as inserting an element at an arbitrary position.


Oh, java.sql.Date interits from java.util.Date, but doesn't obey the "is-a" relationship. This is "clearly" documented, but leads to hibernate giving you "Date"s that are not comparable with your own "Date"s. - davidsheldon
(5) Isn't Stack deprecated these days? I remember seeing somewhere that you should use a Deque instead. - Powerlord
6
[+19] [2010-02-12 10:17:49] ewernli

The Boolean class which defaults to false.

When a boolean is created with Boolean( String ) or Boolean.valueOf( String ) any value other that "true" (ignoring case) will lead to a boolean that is false.

As a consequence, I've seen many property files or configuration with "0", or "No" working correctly, but when toggled to "1" or "Yes" there is no effect.

I wish they had been more strict, and that any value other than "true" and "false" would yield a BooleanFormatException in a way similar to Integer.valueOf( String ).

For other usage we could use parseBoolean( String ) or a BooleanFormatter...


This is not completely true... The boolean constructor does ignore case, so new Boolean("tRUe"); will still yield a true boolean value. I understand, though, that the main concern is the lack of an illegal argument or bad format exception. - Alderath
@Alderath Thanks, I've fixed the sentence to indicate that case is ignored and changed the example using "True" which was incorrect. But the pain point remains. - ewernli
7
[+18] [2010-03-04 16:27:48] SyntaxT3rr0r

One of my biggest Java API gripe is that String's :

.getBytes("UTF-8")

is forcing you to catch a checked exception (UnsupportedEncodingException) which CANNOT happen. ("CANNOT" used as defined by RFC2119)

It cannot happen because if UTF-8 isn't supported by the VM then it's not a compliant JVM for every single JVM under the sun MUST ("MUST" used as defined by RFC2119) support UTF-8 or it is, well, not a JVM.

I've posted about this 10 years ago or so and people have looked at me as if I just landed from a long trip to Mars... Yet of course ten years later a company gave me justice: Google. There's at least one Google Java collection where they acknowledged this as a serious Java API issue and provided a convenience workaround.

Why oh why Java didn't have from the get-go a:

.getUTF8Bytes() 

is beyond me.

In a totally ironic turn of event, the fact that they didn't provide such a method made countless typos in "UTF-8" trigger the UnsupportedEncodingException.

Promise I won't start ranting about checked exceptions (I've got my copy of "Effective Java" next to me and I'll read Joshua Bloch ranting about them for me ;)


(9) +1! Though the problem isn't the lack of String.getUTF8Bytes() but rather the absence of a few static Charset objects for all encodings Java is guaranteed to support, allowing you to say str.getBytes(Charset.UTF_8) - getBytes(Charset) doesn't throw anything checked. It simply makes no sense that you have to look up UTF-8, US-ASCII and other charsets which are guaranteed to be there, and it's not like it's hard to add a few public static final Charset fields in an appropriate place. - gustafc
@gustafc: I agree... But note that due to checked exception with your solution you'd still need to needlessly try/catch the construct. - SyntaxT3rr0r
(1) Well, no - getBytes(Charset) (available from 1.6) isn't declared to throw anything. So if you have a valid Charset you won't have to do any try/catching. - gustafc
@gustafc: oh interesting, lucky you 1.6 ;) I'm developping for OS X and have to support all these older Macs that will never have a 1.6 version :) - SyntaxT3rr0r
8
[+16] [2009-11-08 17:20:51] dfa

int, double, and other primitives cannot be used as generics


(2) Those aren't object types. Use Integer, Double, etc instead. - BalusC
(3) this is a language problem and not library but I totally agree, +1 - flybywire
(6) Annoying for sure, but not an API issue, rather a language issue. - Yishai
(2) Autoboxing almost solves this issue. - fastcodejava
autoboxing wastes memory and cpu-time; it is only a compile-time trick - dfa
(3) Not an API issue. - Rob
thanks for that, so the language can be fast actually. - bestsss
9
[+15] [2009-11-09 03:04:26] Carsten

Not so much an annoyance as just plain wrong: there is a case where the following code can enter the final else {...} part.

if (a==b) { ... } else if (a<b) {...} else if (a>b) {...} else {...}

The case is:

Integer a = new Integer(1); Integer b = new Integer(1);

In case you wonder why: Some comparisons are unboxed, others are not.


(6) Yes. This goes back to using '==' as 'reference equals' and 'primitive equals' operator. Objects should not have operator==, but rather operator=== or a .sameReference method. - KitsuneYMG
That's an awesome example. +1! - Dean J
@kts: Then every object would have to implement ==. Much better to either just test for identity equality (==) or object equality (object.equals(other)). Better yet: if Java had operator overloading, it could do like Python: is for identity equality and == for object equality; if == isn't implemented, it falls back to object identity (in which case, the object identity is object equality). I suppose your proposition would work if the compiler throws an error when an object doesn't implement ==. - Longpoke
(1) The final else is also reached when a or b or both are float or double NaNs. - x4u
@x4u While true, your example is related to an IEEE spec regarding floating point comparisons, not so much Java itself. The use case with primitive wrappers is a result of Java quirkiness. - Michael McGowan
10
[+14] [2009-11-08 17:26:07] Yishai

BalusC beat me to the date API, so I'll list my second one: The fact that clone() is totally broken. I don't think there is anything about the API you could define as not broken, including naming.


(2) If you think the entire API is broken, why bother using it? - Jorn
@Jorn: required at work or school? - 280Z28
Java7 will include "automatic resource management", read: "automatic close". I think the syntax is something like try{ SomeStream = ... } <- close implied (even if return or throw is involved). - java.is.for.desktop
(3) @Jorn, I don't (except to clone an array) as recommended in Effective Java, but sometimes you have to use it because that is how others implemented it, and it is a constant code quality issue on projects. But the real annoyance is that you have to implement your own copy mechanism when a standard one would have been just fine. - Yishai
(3) @java.is.for.desktop: close != clone. - BalusC
(1) @BalusC, thanks, I was trying to figure out what he was referring to. - Yishai
@java.is.for.desktop, I wasn't talking about the finally awkwardness. It won't be in Java7, and has specific challenges over the C# using construct (primarily that it wasn't there from the beginning, making it hard to retrofit on a common interface). - Yishai
(3) What I really hate clone is that it is on Object and not Cloneable. Plus, clone can't return a new object (say from a copy constructor) it must mess with the return of super.clone(). Even though every object has clone (thanks to inheriting from Object), if you try to call it w/o implmenting cloneable, it throws an exception. WTF? - KitsuneYMG
I like Cloneable/clone() - bestsss
11
[+12] [2009-11-08 22:22:36] Dan Dyer

The Cloneable [1] interface does not define the clone method (it's just a marker interface). So even if you know that an object implements Cloneable, you don't know whether it can actually be cloned (it might not have a public clone method).

[1] http://java.sun.com/javase/6/docs/api/java/lang/Cloneable.html

(1) Was there a reason for that? - Liran Orevi
(2) Not that I know of. - Dan Dyer
Sure there was, but you could discuss, if that reason was reasonable :-D You can read in "effective java" about that issue. There are pros and cons. IMHO, the cons are convincing... - Peter Wippermann
It's also misspelled... - Mechanical snail
12
[+9] [2009-11-09 06:13:03] alexander.egger

Closing streams is a night mare.

close() throwing an exception ruins your code and does not help you at all. If you rethrow the exception of close() you loose the original exception and the original exception is usually the important one.

InputStream in = null; 
try {
  in = new FileInputStream(filename);
  // ... some IO operations
} finally {
  // This is the ugly part 
  try {
    if (in != null)
      in.close();
  } catch (IOException e) {
    //Ignore this exception (maybe log it)
    //but never rethrow it.
  }
}

(1) This is not totally true. In TCP sockets you want to know if there is an exception when closing the socket because it might mean that buffered data could not be flushed. - flybywire
@flybywire - surely you are talking about a socket outputstream not a socket inputstream ... - Stephen C
Being fixed in java 7! <code> try (InputStream in = new FileInputStream(filename)) { // ... some IO operations } </code> and that's it! - Kevin Bourrillion
Yes can't wait for that feature in java 7. - alexander.egger
Before Java 7, why not just use Apache Commons IO? It silently closes those extra exceptions in the finally block. - Dean J
If OutputStream.close() throws an exception, you should not ignore it - it may mean that some data could not be written. Same for Writer.close() and all similar cases. - Jona Christopher Sahnwaldt
13
[+9] [2009-11-09 20:10:12] Ally Sutherland

The Exception hierarchy has always been broken in my eyes:

exception hierarchy

I've always thought it would make more sense for all java.lang.Exception and subtypes to be checked exceptions.

Having java.lang.RuntimeExeption inherit from java.lang.Exception but being unchecked is just broken.


(1) @ally.sutherland: the very presence of checked exception is debatable. There are languages that are doing perfectly fine without them. A checked exception is basically a big goto statement. I, for one, am working on a 200KLOC program where we're throwing exactly zero checked exception and the only time where we're forced to catch them is when we're dealing with broken (or legacy and broken) API. Joshua Bloch doesn't have nice things to say about checked exceptions, nor do all the languages authors who wrote perfectly cromulent languages that do not have the concept of checked exceptions. - SyntaxT3rr0r
(5) @WizardOfOdds: "A checked exception is basically a big goto statement" Say what? Argue against them if you like, but that's nonsense. The only logic I can see that would make that a true statement would be true of unchecked exceptions as well. Checked exceptions are a great thing. They're also trivially easy to get rid of if you don't like them: Set up your editor to automatically add throws Exception to every method signature you create. - T.J. Crowder
This is not broken at all. If you declare a method as throwing X then it must be able to throw Y if Y is any subtype of X. So if Y is checked then X must also be checked. I don't think they could have avoided this except by not having a common Throwable superclass. - finnw
14
[+9] [2010-02-17 10:19:20] Gareth Davis

A little pet annoyance is that String#format [1] is static and not an instance method.

I'd like to write:

"My %s format".format("Nice");

instead of

String.format("My %s format", "Nice");
[1] http://download.oracle.com/docs/cd/E17409_01/javase/6/docs/api/java/lang/String.html#format%28java.lang.String,%20java.lang.Object...%29

It looks bad... but perhaps this helps make strings smaller in memory? - Zombies
na wouldn't make much difference. An instance method could in theory be less eligible for inlining by the JIT, but since String is final that goes out the window..maybe we'll be able to use it as an extension method in java 7 - Gareth Davis
And also System.out.println("My %s format", "Nice"); - Pyrolistical
(2) @Pyrolistical isn't that already System.out.printf("My %s format","nice") ?? - Gareth Davis
@GarethDavis, final classes don't help JIT at any rate. They are verified by the Verifier and that's all. JITs do CHA (class hierarchy analysis) instead. Also they can still inline w/ multiple inheritance. - bestsss
Scala fixes this. - Mechanical snail
15
[+8] [2009-11-08 17:47:03] Uri

Oh gosh... I read the JavaDocs of the entire JDK for my Ph.D. and found so many annoyances beyond what already annoyed me from day-to-day programming.

To name a few from my own experience though:

  1. Swing is too intertwined with AWT. IMHO it is a good example of when you have to give up on inheritance.
  2. The text in the JavaDoc that provides instructions for people using a method in an interface or a base class is often mixed with the text for people overriding or implementing that method. No real way to overcome this since there is one javadoc per method, but they could have written this better.
  3. Naming that doesn't convey everything (e.g., Hashtable vs. HashMap and the threading issues).
  4. The date and calendar API. 'nuff said.

That being said, Hindsight is 20/20. It's hard to come up with the perfect API the first time around, and even harder to rectify it while maintaining backward compatibility.


(7) +1 for the last paragraph. And to be honest, I wish people would quit complaining about these things. Nothing is ever perfect. Not even C# ... - Stephen C
(7) My response to Stroustrup: API design is like sex: make one mistake and support if for the rest of your life. --joshbloch twitter.com/joshbloch/status/5177847605 - Pascal Thivent
Post the link to your thesis please :-) - ShiDoiSi
@vs: There's a link from my user profile here, but here it is: cs.cmu.edu/~udekel/papers/UriDekelDissertation.pdf - Uri
Thanks for the link, interesting work! - ShiDoiSi
(1) Any points for the irony of my edit? :D - sje397
16
[+8] [2010-02-11 17:33:35] Adeel Ansari

This one is hilarious. You need to go past to check whether the last column read was null or not.

This is the case when you get 0 from any of these ResultSet's getInt(), getDouble() etc. methods. Then you have to check it whether it was really 0 or null, by invoking wasNull() on the ResultSet.


(1) That's indeed hilarious (+1). That's also why ResultSet#getObject() is better: stackoverflow.com/questions/2158187/… - BalusC
17
[+7] [2009-11-08 17:54:46] Martin

I hate the fact that Java does not allow extracting static class metadata at compile (=coding) time. For example, there is no way to statically to refer to a function's name or a field's name for later reflection-use (for example). You must use a dummy constant (final static String FIELD_NAME = "fieldName") instead which is dumb as it could be more easily solved via native meta data reference (think enum and think enum's getName etc. or similar).

However, http://projectlombok.org/ can spice up java just like that.

But why is this not yet native java fuctionality? It should have been for so long now ...


18
[+6] [2009-11-08 17:19:19] flybywire

Mine is that java.util.Map.get does not accept a default object if they key is missing in the Map.

Therefore I find myself too much writing this code:

Object value = map.get(key) == null ? default : map.get(key);

UPDATE

After Pascal's comment showed me how all my code is buggy, should have been:

Object value = map.containsKey(key) ? map.get(key) : default;

(10) What if the value associated to key is actually null? - Pascal Thivent
That's more a language problem, not an API problem. If it really annoys you, switch to C#: Object value = map.get(key) ?? default; (called the null-coalescing operator), or wait until future Java releases (as far as I know, it won't be in Java7). - BalusC
In .NET we have if (!map.TryGetValue(key, out value)) value = defaultValue; - 280Z28
Take a look at the DefaultedMap: commons.apache.org/collections/apidocs/org/apache/commons/… - Jorn
Originally I thought this post was about the performance issue involved in not having a GetOrAdd method, but that's not the case since you're getting the key twice. TryGetValue is perfect for the use here, and the new ConcurrentDictionary type in .NET 4 does have a GetOrAdd method, which takes either a value or a function to lazy-eval: msdn.microsoft.com/en-us/library/ee378676(VS.100).aspx - 280Z28
I should really add: I'm not trying to say "Java sucks use C#" at all - I'm merely showing an example of something I think is clean and you could actually take and make work in Java and your problem would go away. - 280Z28
19
[+5] [2010-02-11 17:53:41] ewernli

The XML APIs: SAX, DOM, StAX.

I agree that stuffs have improved with StAX, but it is still waaaay to complicated. We can of course blame XML for being an "only apparently" simple technology. Dealing with namespaces, entity, CDATA, etc. can make a trivial problem become a nightmare.

But I still haven't digested the ugliness or reading XML with SAX and DefaultHandler#character() being sometimes called more than once per tag. Even if there is a rationale for that, it's still bad API to me.


I actually like SAX, though it's not easy to use, but nowadays I prefer StAX, which is really quite nice. Is something wrong with me? :-) - Jona Christopher Sahnwaldt
20
[+4] [2009-11-08 17:48:51] Rob Smith

+1 for Date/Calendar API

Also the implementation of generics is pretty bad. Type erasure leads to some weird situations that are difficult to deal with. Also wildcards are confusing from time to time even after using them for years. One more gripe is that the generics syntax is overly verbose:

Map<Integer, String> someMap = new HashMap<Integer,String>();

This will be fixed in Java 7 with generic type inference so the above line will end up looking like this:

Map<Integer, String> someMap = new HashMap<>();

unfortunately, generics had to be implemented in such a way as to not break backwards compatibility, which I think led to type erasure. - Peter Recore
21
[+4] [2009-11-09 03:32:27] pst

ByteBuffer as a Class with no corresponding Interface in NIO.

There is no way to create a "custom" ByteBuffer implementation. (ByteBuffer can not be extended due to access levels of the constructors.)


Why do you need to? - KitsuneYMG
22
[+4] [2009-11-09 19:39:56] Pavel Minaev

I hate how JDBC PreparedStatement derives from Statement, and then proceeds to override half of the latter methods (essentially all that make it a "statement") with throwing stubs, replacing them with its own equivalents.

Ultimately, it exposes the design flaw of Statement class, instances of which - contrary to its name - do not represent statements at all. Instead, they are kinda result cursors in disguise (due to "one open ResultSet per Statement" rule), though what's the purpose of having such an object is completely beyond me.


23
[+2] [2009-11-08 18:13:16] I. J. Kennedy

String comparison:

if ("somestring".equals(foo)) ...

instead of

if (foo == "somestring") ...

"You can't be serious!" -- John McEnroe


(1) Yes it can, foo == "object" is comparing references. The "object" is an actual object, you can use the string functions off of the string. - monksy
(2) If you override == to indicate string equality, how would you see if two strings were the same object? - Thorbjørn Ravn Andersen
(1) @Thorbjørn: why would you want to? - Jeremy Stein
(1) @Thorbjørn: you'd check for object equality with .equals(Object). If they were reversed, the much more common case would be easier. - Dean J
(1) @Dean, then you would make String a special case breaking Object comparison and probably serialization too just because you like one syntax better than another? - Thorbjørn Ravn Andersen
(2) @Thorbjørn: no, I would have designed it that way from the start. You can't change it for just strings, but it sure would have made a lot more sense (and saved a lot of keystrokes) if the spec was the other way around. - Dean J
Scala fixed that - it uses "==" for equality and "eq" for identity. - Jona Christopher Sahnwaldt
The real annoyance is not related to Strings, but with references in general. To '==' operator should not have been assigned to a relatively rare operation (in common use one is interested in object equality, not in reference identity). As mentioned above, Scala makes much more sense here. - leonbloy
24
[+2] [2009-12-03 23:37:00] monksy

My recently found annoyance with Java.

BufferedImages [1] have the functions getRGB and setRGB which are nice, however they return an int and not Color. So if you would like to get the individual components without direct manipulation you would have to create a color object just for that, and then convert it back to int just to set the RGB.

[1] http://java.sun.com/j2se/1.4.2/docs/api/java/awt/image/BufferedImage.html

@steven: Image manipulation is typically something much more demanding than any "enterprise app" you can imagine. This is done for performance purpose: it is very common process indivual pixels using getRGB(). Imagine the potential millions of needless objects you'd be creating only to get alpha, red, green and blue and then modify them and then use setRGB(). Using getRGB() on every single pixel of a screenshot of my 1920x1200 screen would produce 2.3 million objects! Objects abstraction have their limit: individual pixel manipulation being one of them (more is following) - SyntaxT3rr0r
@steven: You don't see Maya and 3DSMax and high-performance image manipulation library being efficient by using a too low level of abstraction. You see them being efficient because their programmers know that (x >> 8 & 0xFF) give them the green component. - SyntaxT3rr0r
25
[+2] [2010-02-17 10:06:41] Andi

A decent class for simple monetary calculations. BigDecimal is a right PITA to use if all you want is to do some invoicing for instance.

There isn't even a method to quickly multiply by an integer or calculate a percentage. Would be great to have a class Monetary capable of these things.

I'm thinking along the line $12.98 * 5 * 12.5%

Monetary m = new Monetary("12.98");
Monetary tax = m.multiply(5).percentage(12.5)

you should be using (psuedo) fixed point arithmetic for currencies, (calculate in cents not dollars) - ratchet freak
26
[+2] [2011-07-29 11:17:18] pavnic

I have two favorits regarding java collections (beside some allready mentioned here):

1) java.util.Map<K,V>.get : takes Object as argument not K as parameter type. I don't know if there is any good reason for this, I think its just anoying. If you change the type arguemnts of the Map instance you do not get any feedback from the compiler that your call to Map.get is faulty.

2) Searching java colelctions: java.util.Collection<T> just defines contains with a single argument of type (again) Object (why object and not T?) so I have no possibility to search the collection for other predicates than equals. Ironically there exists an interface called Compareable, which seems only to be used by binarySearch, not by contains, and sorting all your collections all the time is not very useful IMHO.


(1) I'm not 100% sure, but it seems a lot like backwards compatibility with pre-1.5 versions of Java which didn't have generics. - mjomble
Possibly because .equals (which is what almost all maps use to do the lookup) is defined on Object, not on K. Would it have been possible to make it so that you could only call equals on two objects of the same type? I'm not sure, especially because it's not clear what "same type" would mean in this case. - MatrixFrog
Generics are not used well in most parts of pre-1.5 API. Map is actualle my favorite example, but there is more. Cloneable (besides other issues) should be Cloneable<T extends Cloneable> - Raphael
27
[+1] [2009-11-16 19:39:02] Trick

Integer, Double,... comparison.

if (oneDouble.compareTo(otherDouble) > 0)

or

if (oneDouble.isGreaterThan(otherDouble))

and of course all the analog.


28
[+1] [2009-11-16 19:41:53] Bryan Kyle

(Input|Output)Stream.close() throws a checked exception which means you have to litter your stream handling code with nested try/catch blocks.


29
[+1] [2010-02-24 18:15:31] Bigwheels

The proliferation of CHECKED exceptions throughout the API. Most notably, java.sql.SQLException and java.io.IOException. They should be unchecked exceptions.

Adding throw statements up your call stack until you get to the method that can handle them is ugly and tedious. And the nested Try-Catch-Finally's to close jdbc connections are a joke.


IMHO they should have had an Unchecked interface instead, then some specific exceptions that are clearly programming errors (e.g. SQL column index out of range, trying to write to a closed stream) could be uncheckd while exceptions that were outside the programmer's control (e.g. file not found, unexpected SQL schema change) would remain checked, and this would be orthogonal to whether the exception came from java.sql or some other subsystem. - finnw
@finnw that's an improvement, but for instance, a SQL schema change exception would be thrown so rarely it's not worth it to put code in there to handle that. and besides if it is thrown, how are you going to handle that anyway? in most cases that's not something you would handle with code anyway. - Bigwheels
Ideally you would handle it by closing and recreating the PreparedStatement and retrying the transaction (which well-written programs are capable of doing anyway.) And it's not super-rare for web apps. Some apps (like StackOverflow) just go offline for a couple of hours if they need to change the schema, but some apps really must not go offline and must handle schema changes (facebook, google web search etc.) Others (Twitter) shouldn't go offline but do. - finnw
Well, I think we are talking about different things in regards to schema changes. But my point is that I shouldn't have to handle exceptions that I don't want to or am not prepared to handle. The decision on whether or not to handle an exception should not be made by the "called method", it should be made by the "calling method". That last sentence is the main idea. - Bigwheels
30
[+1] [2010-03-01 15:39:40] Arne Burmeister

The collection api is mutable - thats ugly. But why there are to similar types Enumeration and Iterator? They just can have made Iterator extends Enumeration and introduce Enumerable instead of Iterable in Java 5. Now you always have to deal with both, adapt one to the other, i hate it.


java.util.Collections.enumeration() and java.util.Collections.list() may help. - Jona Christopher Sahnwaldt
31
[+1] [2011-07-27 15:40:34] finnw

(copied from question 169815 [1])

This one still catches me out occasionally:
When you create a duplicate [2] or slice [3] of a ByteBuffer [4], it does not inherit the value of the order property [5] from the parent buffer, so code like this will not do what you expect:

ByteBuffer buffer1 = ByteBuffer.allocate(8);
buffer1.order(ByteOrder.LITTLE_ENDIAN);
buffer1.putInt(2, 1234);

ByteBuffer buffer2 = buffer1.duplicate();
System.out.println(buffer2.getInt(2));
// Output is "-771489792", not "1234" as expected
[1] http://stackoverflow.com/questions/169815/java-common-gotchas
[2] http://java.sun.com/javase/6/docs/api/java/nio/ByteBuffer.html#duplicate()
[3] http://java.sun.com/javase/6/docs/api/java/nio/ByteBuffer.html#slice()
[4] http://java.sun.com/javase/6/docs/api/java/nio/ByteBuffer.html
[5] http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4715166

32
[0] [2009-11-08 18:47:50] MAK
  1. The java.math.BigInteger class is a total joke without operator overloading. Something as simple as (a+b)-c becomes (a.add(b)).subtract(c).

  2. Lack of a MultiSet container.

+ the points raised in other posts (especially Date).


(1) code.google.com/p/google-collections has multi-set (among others). I believe apache-collections does too but is still 1.4 (no generics). I remember hearing about a project to fix it, but don't know what happened to it. - KitsuneYMG
Thanks for the google-collections reference. I'm trying it our right now. - MAK
this seems more like a language problem (no op overloading) than an api problem. - Peter Recore
33
[0] [2009-11-09 03:24:09] Dan Watt

Aside from SimpleDateFormat not being thread safe, the equals and hash code methods of java.lang.URL [1] doing external lookups, which is particularly annoying if the addresses point to two different virtual hosts with the same IP address.

[1] http://java.sun.com/javase/6/docs/api/java/net/URL.html#equals%28java.lang.Object%29

34
[0] [2010-02-12 12:47:42] Tadeusz Kopec

Collection interface has contains method which returns boolean but no find method. Set doesn't have find either, so it ends up with

Map<Type, Type> myMap = new HashMap<Type, Type>();
myMap.put(obj, obj);

or similar.


Isn't the contains method sufficient? You need a reference to the target object to call contains anyway so returning a boolean is sufficient. If you want to search the data structure then you need to iterate over its elements. - maerics
(1) Have you ever heard about overriding equals? Do you iterate over HashSet to find specified element? - Tadeusz Kopec
35
[0] [2010-03-04 16:59:32] maerics

The inconsistent iterator pattern.

In Java you have the Iterator and Enumeration interfaces for iterating over sequences. Moreover, the JDBC class ResultSet has its own iteration pattern via the next method. There should be a single, language-supported way to iterate ordered sequences.

The introduction of the for-each loop in Java 1.5 helps for arrays and Iterators, but enumerations and result sets still have their own styles, so if you want to iterate over a sequence you must know what type of sequence it is.


And don't forget PathIterator - finnw
36
[-1] [2009-11-08 18:54:50] Atmocreations

that a method having an argument of type

MyClass<AnyType>

leads to the same signature as

MyClass<AnotherType>

does...


(4) I believe you are looking for the phrase "Type Erasure" - KitsuneYMG
(1) @Atmocreations: +1... Type erasure is a huge failure. Most programmers don't realize how utterly broken the weak parametric polymorphism provided by generics is. It works for nothing but the simplest of the OO hierarchy, where there's no hierarchy at all. But they don't realize it, because all they do is procedural programming with an over-reliance on the default Java collections (where, granted, the weak parametric polymorphism provided by generics is useful)... Unless you're modeling collections, you better avoid generics in your class or they'll fire back. Been there, saw their limitations. - SyntaxT3rr0r
37
[-2] [2009-11-08 17:21:23] Artem Barger

Missing of operator overloading.


(3) That isn't an API issue, rather a language issue, but I think just like they made an exception for + on String, they should have made exceptions for the built-in numeric APIs, such as BigInteger and BigDecimal. - Yishai
Right it's not an API, but still it's very missing for me. - Artem Barger
A hot debated issue. But most Java programmers seem to like it that way. The experience from C++ and C# demonstrates us that most people tend to use operator overloading in a confusing way. - java.is.for.desktop
(3) Operator overloading means you can never be certain that what you see, means what you think, unless you CHECK! EVERY TIME !! Sigh :( - Thorbjørn Ravn Andersen
(1) This is indeed some a problem, I recently had to create an adapter class for an updated interface and the actual implementation is made so that each type of class implementing the interface is a singleton. Easiest way to test the equality? == and !=, of course - except since I can't overload operators, I can't make my SomeClassImplementingInterfaceWrapper == SomeClassImplementingInterface, instead I have to override equals() and hashCode() and just hope no one took the shortcut of using == or != in the old code... - Esko
38
[-4] [2009-11-08 18:04:49] Hai

I think java persistent API


(3) -1; give a rationale. - Rob
39