Shyam has posted 8 posts at DZone. You can read more from them at their website. View Full User Profile

What I Miss in Java

11.06.2009
| 8421 views |
  • submit to reddit

So I finally got some time to sit down and write, after being knee deep in work the past month or two. And without a doubt, I wanted to write about what has been heckling and annoying me over the past month. I am an ardent defender of Java as a good language, especially defending it from Misko day in and day out, but even I will agree that it does suck at times. So today, Java, the gloves are off. I love you, but this is the way things are.

To give some context, I have been working on GWT a lot recently, and have done some crazy things with GWT generators (which I might cover in a few posts later). I love GWT, but for all of GWT’s aims to allow developing modern web apps without losing any of Java’s tooling support, there are a lot of things which are made easier in javascript. Lets take a look at them one by one, shall we?

Closures (Abiity to pass around methods)

So this was the straw that broke the camel’s back. I had this use case today where I wanted to set some fields through setters on a POJO. Simple enough right? Well, NO, because someone used defensive programming (Don’t get me started about precondition checks, thats for another post) and so it through a null pointer exception. Ok, since I can’t change the POJO (since it is in someone else’s code base), I needed to check for nulls on my side and not call the setter if the value was null. Simple enough, I do a check and call the method conditionally. Except when you have a few 10 odd properties, thats a lot of conditionally crappy code.

Ok, so my other option is write a function which checks that, right? Except in Java, you can’t pass around functions or closures. Ideally, I want to have a closure which takes a value and a function, and let the closure handle the null check and conditional calling. Something like :

callConditionally(myPojo.setValue, actualValue);

Except you can’t. Not in java. I mean, I could create an interface to wrap it, but that just adds more boilerplate than necessary. I ended up creating a method which uses reflection to find the method by name and calls it, but my point is that it shouldn’t be necessary. What should be two or three lines of code ended up being a 20 line monstrosity. And yes, before some smart aleck replies that if I wanted closures, I should go to javascript, I will point out that there have multiple proposals to include closures in Java, and Scala, which compiles into java, supports closures as well.

There are multiple JSR’s and open source libraries which try to implement this for Java, and one of these days, I’m gonna give it a try. But for those interested, check out http://javac.info/ and http://code.google.com/p/lambdaj/. Both of them look promising.

Type inference and General Wordiness

They say a picture is worth a thousand words. Well, with java, and especially with generics, it seems that even a simple declaration is atleast a thousand words. For example :

Map<String, List<String>> myMap = new HashMap<String, List<String>>();

The above line could be so much shorter and sweeter as :

Map<String, List<String>> myMap = new HashMap();

There are very few cases when I would want a map of something else when I just declared it of a particular types. Other examples like reading a file, working with regexes abound, all of which require much more syntax than other languages. And I definitely do miss being able to say

if (myValue)

instead of

if (myValue != null)
Sigh… And don’t even get me started with reflection. Reflection in Java is extremely powerful, but man is it wordy. Not only can you not recurse over the properties of an object directly (like say, in javascript), you also have to worry about exceptions (which I’ll get to in the next section)

Checked exceptions

That brings me to my last and biggest complaint. Checked exceptions in Java. They are just plain evil. I know people swear by them, and some of their arguments even make sense. Sometimes. But the fact remains that they make me write more boilerplate, more code that I don’t even care about than anything else in Java. The idea behind checked exceptions is sound. Its a great way to declare what the caller of a method needs to worry about. But the thing is, I should have an option other than rethrowing or logging it.

I did a very unscientific data gathering experiment of just looking at code randomly in different code bases (Codesearch was especially useful for this). And the majority of catch blocks I found either

  • Logged it using logger or System.err
  • Rethrew it as a wrapped exception

Me personally, I have changed Eclipse to generate all catch clauses for me by wrapping and rethrowing it as a RuntimeException so I don’t have to worry about adding a throws to my method declaration, when it is a non recoverable exception for the most part.

Furthermore, sometimes Checked exceptions can even lead to clauses which will never ever be executed. Point in case :

try {
java.net.URLEncoder.encode(myString, "UTF8");
} catch (UnsupportedEncodingException e) {
// Can never be thrown, but I am forced to catch it.
// Because its a checked exception!!!
}

There are many more cases like this, but I think this is enough of a rant for now.

From http://theshyam.com

Published at DZone with permission of its author, Shyam Seshadri.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Tags:

Comments

Mladen Girazovski replied on Fri, 2009/11/06 - 7:37am

I understand all of your points, except this one:

 if (myValue)

What is the problem here?

Do you want to treat NULL like boolean?

Michal Huniewicz replied on Fri, 2009/11/06 - 8:12am in response to: Mladen Girazovski

I think Shyam would want not only null to be treated as a boolean, but every object too (so: null = false, non-null reference = true). Applicable for primitives as well, I guess.

Dennis Waltmann replied on Fri, 2009/11/06 - 8:16am

Hey Shyam,

I don't share your complaint about checked exceptions in Java. In fact, you are complaining about bad usage of checked exception not the feature itself. Intention of the exception type mentioned is that the invoker of the method throwing a checked exception can react programmatically to avoid the exception on the next invokation. In other words: If the reason of the exception is inevitable the developer of a method should not throw a checked exeption but rather an unchecked one.

Matter of fact, there are plenty of examples where the exception thrown should inherit RuntimeException instead of Exception but the possibility to have an In-Your-Face way to publish an obvious and expected exception is valuable.

Any good?

Ta

Dennis

Thibault Delor replied on Fri, 2009/11/06 - 9:47am

Hello,
i won't comment closures because i don't master the subject, but for the rest i totally disagree. I'm ok with your Hashmap syntax and java 7 will solve your problem with the diamond syntax.

Like dwaltmann say, the problem isn't checked exception, it's the bad use of checked exception. If we remove checked exception, we'll have a programming language too much permissive. I think that the goal of java is to force the developper to code as clean as possible. If we remove checked exception we remove the fact that some exceptions must be treated and so, if you use an external library, you'll have more chances that some exceptions are not catched and you'll have no way, without looking at the code if you can, to know what kind of Exception can be thrown before it's thrown. Of course you'll never sheltered from RuntimeException, but here it's a choice of the programmer. I think that Checked Exception must be seen as the possibility of the developper to say "hey, here you have an exception that has a big chance to happen, you have to carry about!". The problem is just the use of that and the problem is the developper, not Java.

For the if(myobject), i don't think it's very painful to write ==null and at least the programmer know what he does.

I think that you complain about that because you are a good programmer who know exactly what he does and know basics rules of clean programming. Permissiveness can be a real benefits for you, but unfortunately that's not the case for everyone, the more you add permissiveness, the more you risk spaghetti programming.
Thanks for us, bad programmers prefer PHP :D (joke)
PS : sorry for my english :s

Jose Smith replied on Fri, 2009/11/06 - 9:59am

According to this article:

 http://java.dzone.com/articles/jdk7-tackles-java-verbosity

Java 7 already has simplified generics:

Map<String, List<String>> myMap = new HashMap<String, List<String>>();

becomes

Map<String, List<String>> myMap = new HashMap<>();

 

 Also, I'm not a fan of  "if (someObject)"

For example what would happen in the example:


Boolean valid = null;
.
.
if (valid)
{
  // do something
}

 

Andrew Arrigoni replied on Fri, 2009/11/06 - 11:22am

For the most part, I agree. Closures would simply much of my code. For particularly good programmers, a preprocessor would allow us to do much of the same thing. I'm not really ready to cross that bridge though.

Bad usage of Checked Exceptions in the core system libraries would be a problem with the language itself, IMO. Not saying we should toss Checked Exceptions but large parts of the Java libraries could probably use some enhancement in this matter. The null fails on if concept would be a nice bit of syntactic sugar, IMO. != null is another point for bugs to creep in. The less code I write, the less places bugs can be. :)

Chris Knoll replied on Fri, 2009/11/06 - 11:35am

Re: Checked exceptions:

This isn't a problem with the Java, per se, but rather the approach was adopted by the very early programmers that every exception in the JDK extended Exception (with some rare cases where RuntimeException is used).  Instead, they should have had a root exception Exception, and then 2 subclasses: CheckedException and UncheckedException, and had all the exceptions in the JDK extend those depending on if they wanted that particuar exception checked or unchecked.  (And if posisble, prevent the subclassing of Exception directly so that you either extend CheckedException or UncheckedException...but that's a big change).  naturally, being the know-it-alls that they are, they would hav made everythign a CheckedException, so we'd probably be in the same place we are today..but I digress.

Besides...having a separte type of exception called 'RuntimeException'?  As opposed to what...'CompiletimeException'?  All the exceptions thrown in code are at runtime!  That framework was actually put together quite stupidly, actually.

IMO, they should just make Exception unchecked by default in the next JDK relase.  It won't break any existing code (you're relaxing constraints, not enforcing new ones).  That would certainly be an easy change to fix one of the sorespots in Java development.

 Re: shorthand for generic var declaration

 Can't say i like this shorthand...too easy to miss the <> without the params, why didn't they just put the NEW declaration part of the variable declaration as so:

new HashMap<String, List<String>() myHashMap;

but this looks a little funky and maeks the constructor declaration look out of place, so perhap introduce an 'as' keyword like so:

hashmap<String, List<String>> myHashmap as new();  // if the object requires a constructor param, you would pass it to the new

saves typing, and is (again, IMO) more indicative of wha tthe developer intends: to declare a new HashMap of a particualr type (as opposed to declaring a reference to a Hashmap of a partiuclar type)

 -Chris

 

Alen Vrecko replied on Fri, 2009/11/06 - 11:35am

Imho a non-negligible share of the problem is that the whole Java Standard Library is overdue for an overhaul. They went totally overboard with using Checked Exceptions at this many places. I hate it very much. But you can definitely use some good libraries to patch the problem a little bit.

Map<String, List<String>> myMap = Maps.newHashMap();
Encoders.encode(myString, Encodings.UTF8);
Properties2.of(MyClass.class).visit(....);
etc...

Philippe Lhoste replied on Fri, 2009/11/06 - 11:48am

I agree with closures, but the topic have been beaten to death, and finally rejected out of Java 7. Alas.

I have also seen many heated debates about checked exceptions, I am not too sure about these, now... :-)

I deeply disagree with the if (myString) part, it opens a can of worms. Actually, when I code in JavaScript or C, I still use this syntax only for boolean variables, I prefer to do explicit checking of values otherwise. (But then I cringe when I see if (bCheck == true)...)

Opening it even more as Michal suggests is even worse, as it mixes badly with "assignment is expression", with the "good" old C trap if (a = b)

On the wordy syntax with generics, beside the possible Java 7 solution, I believe the Google Collections library offers interesting solutions to this (and more!). Not sure, as I hadn't yet the opportunity to try it.

Shyam Seshadri replied on Fri, 2009/11/06 - 12:31pm

With regards to generics, yes, Google Collections solves a lot of it, and offers some really nice syntax which I can't live without. especially with a static import, i can do Map myMap = newHashMap(); and be done!

My point with the if(value) was not to say that it needs to be there, but that in general, Java has chosen the more wordy alternative over something simpler in almost every case. Be they generics, checked exceptions which have to be try caught (even when they cannot possibly happen!!!), and so on and so forth.

I agree that checked exceptions have been badly used, but consider this situation :

I am writing an implementation of an interface (interface not in my codebase), and I work with say, JDBC. Now JDBC will throw some checked exceptions, and I cannot rethrow them, because the interface will not allow additions. So now I am forced to try catch and handle them at this point, or throw them as a runtime exception when I really do not want to handle it at this level? So either I create my own RuntimeException subclass which I handle separately, or I am forced to handle it at this level.

Also, ByteArrayOutputStream and the example I gave with URLEncoder and URLDecoder force you to catch checked exceptions which cannot possibly happen in a lot of cases!! I would rather the method tell me what all it can throw in what cases, and let me decide which ones I care about and can recover from, and not force me to catch ones which

  • cannot happen or
  • I can't recover from.

I mean, isn't that the whole point of exceptions?

Misko's article is another good take on this : Checked exceptions i love you but you have to go

Nils Breunese replied on Fri, 2009/11/06 - 4:07pm

Have you tried Groovy? I believe it solves (almost) all gripes you mentioned: http://groovy.codehaus.org/

Loren Kratzke replied on Fri, 2009/11/06 - 5:11pm

My theory is that those who complain too loudly about checked exceptions must be on a tiny team writing trivial code meant for end users that have no financial stake in the functions being performed by the code - a.k.a mission trivial applications.

Checked exceptions tell you what can go wrong, where it will happen, and the opportunity to do something about it is yours to squander if you wish. An empty catch block only takes one line of code.

Syntactical sugar for generics coming in Java 7.

Shyam Seshadri replied on Fri, 2009/11/06 - 7:36pm in response to: Loren Kratzke

Uh no, Checked exceptions force down my throat things that may or may not happen. I agree that yes, that is what it is supposed to be for, but it has been overly misused, and especially bad when you try to work with two or more libraries, one of which tells you that no exceptions can be thrown by a method while the other one u use in it tells you that it will throw that exception without caring for what you do with it.

And I would argue that the empty catch block is much much worse than anything, since my eyes tend to get used to those, and then you start ignoring it when it really matters. It should not be the norm, where most checked exceptions are logged or rethrown as RuntimeExceptions. Exceptions should be when you truly care about an error and want to try and recover from it, not Window.alert() it!

And I would have taken closures over the syntactic sugar in java 7 since you can get that from the Google Collections library, but that got voted out, sadly.

Shyam Seshadri replied on Fri, 2009/11/06 - 7:36pm in response to: Nils Breunese

Groovy is on my list to play around with, along with Scala which I am trying out nowadays.

Raphael Miranda replied on Fri, 2009/11/06 - 8:28pm

In groovy null references, empty lists, 0 or empty strings("") resolve to false, everything else is true. It improves redability quite a bit.

Mike Mormando replied on Sat, 2009/11/07 - 12:31am in response to: Shyam Seshadri

Have you ever worked on a service oriented project using Spring remoting? Where the guys that put it together, all ardent worshippers at the alter of Rod Johnson, get it into production, sell upper management that THIS is the ONLY way to go forward, and then quickly go elsewhere? I keep getting these weird errors, out of no where, with no warning, which the only way I am EVENTUALLY able to figure out what is going on is to see what triggered a ClassNotFound exception! I'll take having to worry about redundant stupid exceptions on closing a jdbc connection/resultset/statement whatever over it going the other way ANY DAY!

Martin Wildam replied on Mon, 2009/11/09 - 6:03am

I also don't share the opinion with the checked exceptions. I am glad that I have both options in Java - create runtime (unchecked) or checked exceptions.

That in some libraries for some methods a wrong decision has been made when choosing the type of exception(s) thrown is a different point...

Kit Davies replied on Mon, 2009/11/09 - 8:41am

Re. closures, FWIW, I believe Project Lombok are looking at generating anonymous class impls in the AST by applying an annotation to a block of code in Eclipse, much as they generate getters/setters for fields, etc.

 This will give you "closures" (ie. first-class code blocks) with very little boilerplate.

Regards

 

Carl Smotricz replied on Mon, 2009/11/09 - 8:53am in response to: Shyam Seshadri

I share your distaste for the wordiness of Java. So this weekend I started trying to write a "real" application in Scala.

My experience so far: In straightforward application code, when you have to do A then B then C, Scala saves you a few words of declaration and the semicolon at the end of every line. So far I've only found 1 or 2 opportunities to write elegant functional code to accomplish a data transformation. But oh the complex sneakiness of the language! The many rules and their exceptions! I found myself wishing for the (relatively) unambiguous simplicity of Java. I came away thinking Scala is a language for people smarter than myself.

Far be it from me to pre-bias anyone against Scala! But I'd be very interested to hear what you, as someone "smarter than myself" think about Scala - I'm looking forward to hearing about your Scala experiences!

 

Mike P(Okidoky) replied on Mon, 2009/11/09 - 4:18pm

I think Scala is far beyond any of the languages I've seen so far, and it's not performance challenged like Groovy. The only thing really missing in Scala is break/continue. The throw/catch hack Martin (Scala guy) provides is unacceptable.

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.