tags:

views:

2299

answers:

37

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

+5  A: 

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;
flybywire
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: http://commons.apache.org/collections/apidocs/org/apache/commons/collections/map/DefaultedMap.html
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: http://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
+11  A: 

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

dfa
Those aren't object types. Use Integer, Double, etc instead.
BalusC
this is a language problem and not library but I totally agree, +1
flybywire
Annoying for sure, but not an API issue, rather a language issue.
Yishai
Autoboxing almost solves this issue.
fastcodejava
autoboxing wastes memory and cpu-time; it is only a compile-time trick
dfa
Not an API issue.
Rob
+61  A: 

java.util.Date is one and all epic fail. The Calendar isn't much better. I am really looking toward JSR-310. Until then Joda Time 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 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.

BalusC
+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
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
@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
http://msmvps.com/blogs/jon_skeet/archive/2009/11/02/omg-ponies-aka-humanity-epic-fail.aspx -- "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
...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
@Brian Agnew, yes that's the name. Have a look at http://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.
day_trader
A: 

Missing of operator overloading.

Artem Barger
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
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
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
+11  A: 

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.

Yishai
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
@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
@java.is.for.desktop: close != clone.
BalusC
@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
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
+22  A: 

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

Brian Agnew
+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
Thread-safety makes slower... You should only make things thread safe if you need to.
Thorbjørn Ravn Andersen
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
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
Brian - I found a fix :)http://joda-time.sourceforge.net/api-release/org/joda/time/format/DateTimeFormatter.html
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
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
The shared state in SimpleDateFormat is the Calendar object used to decompose the date/time into its components.
Mark Thornton
@Mark, and that is probably because the Calendar is heavy, heavy, heavy, which leads us back to http://stackoverflow.com/questions/1697215/what-is-your-favourite-java-api-annoyance/1697229#1697229
Thorbjørn Ravn Andersen
+7  A: 

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 wrote 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.

Uri
+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
*My response to Stroustrup: API design is like sex: make one mistake and support if for the rest of your life.* --joshbloch http://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:http://www.cs.cmu.edu/~udekel/papers/UriDekelDissertation.pdf
Uri
Thanks for the link, interesting work!
ShiDoiSi
+3  A: 

+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<>();
Rob Smith
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
+17  A: 

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.

Adamski
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
Isn't Stack deprecated these days? I remember seeing somewhere that you should use a Deque instead.
R. Bemrose
+4  A: 

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 ...

Martin
A: 

I think java persistent API

Hai
-1; give a rationale.
Rob
+19  A: 

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

See also "Ten Little Soul Crushing Features of Java"

Dave Ray
+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
That's not a good excuse. Join could use the regex to randomly generate delimiters :)
Dave Ray
+1  A: 

String comparison:

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

instead of

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

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

I. J. Kennedy
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
If you override == to indicate string equality, how would you see if two strings were the same object?
Thorbjørn Ravn Andersen
@Thorbjørn: why would you want to?
Jeremy Stein
@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
@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
@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
A: 
  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).

MAK
http://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
A: 

that a method having an argument of type

MyClass<AnyType>

leads to the same signature as

MyClass<AnotherType>

does...

Atmocreations
I believe you are looking for the phrase "Type Erasure"
KitsuneYMG
@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.
Webinator
+48  A: 

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.

davidsheldon
luckily they fixed that with the URI class
Jorn
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 P.
+9  A: 

The Cloneable 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).

Dan Dyer
Was there a reason for that?
Liran Orevi
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
+11  A: 

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.

Carsten
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
A: 

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

Dan Watt
+2  A: 

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.)

pst
Why do you need to?
KitsuneYMG
+3  A: 

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.
  }
}
alexander.egger
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
+30  A: 

Poor choices for of names are a favourite pet hate.

Classes which extend a class of the same name.

java.sql.Date extends java.util.Date

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.
Peter Lawrey
The poem made me almost cry (of laughing).
Lluis Martinez
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
I thought you just made up that class name until I googled it. Dear god
TheLQ
+3  A: 

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.

Pavel Minaev
+7  A: 

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.

Ally Sutherland
@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.
Webinator
@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
A: 

Integer, Double,... comparison.

if (oneDouble.compareTo(otherDouble) > 0)

or

if (oneDouble.isGreaterThan(otherDouble))

and of course all the analog.

Trick
+1  A: 

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

Bryan Kyle
+2  A: 

My recently found annoyance with Java.

BufferedImages 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.

monksy
@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)
Webinator
Webinator
+6  A: 

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.

Adeel Ansari
That's indeed hilarious (+1). That's also why `ResultSet#getObject()` is better: http://stackoverflow.com/questions/2158187/how-do-i-get-a-double-out-of-a-resultset-instead-of-double/2158354#2158354
BalusC
+3  A: 

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.

ewernli
+7  A: 

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...

ewernli
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
A: 

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.

Tadeusz Kopec
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
Have you ever heard about overriding `equals`? Do you iterate over HashSet to find specified element?
Tadeusz Kopec
+1  A: 

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)
Andi
+8  A: 

A little pet annoyance is that String#format 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");
Gareth Davis
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
+1  A: 

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.

Bigwheels
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
+1  A: 

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.

Arne Burmeister
+8  A: 

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 ;)

Webinator
+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.
Webinator
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 :)
Webinator
+1  A: 

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.

maerics
And don't forget `PathIterator`
finnw