Scott is a Senior Software Architect at Altamira Corporation. He has been developing enterprise and web applications for over 15 years professionally, and has developed applications using Java, Ruby/Rails, Groovy/Grails and Python. His main areas of interest include object-oriented design, system architecture, testing, and frameworks of all types including Spring, Hibernate, Ruby on Rails, Grails, and Django. In addition, Scott enjoys learning new languages to make himself a better and more well-rounded developer a la The Pragmatic Programmers' advice to "learn one language per year." Scott is a DZone MVB and is not an employee of DZone and has posted 43 posts at DZone. You can read more from them at their website. View Full User Profile

Can Java Be Saved?

11.10.2009
| 18041 views |
  • submit to reddit

The Java language has been around for a pretty long time, and in my view is now a stagnant language. I don't consider it dead because I believe it will be around for probably decades if not longer. But it appears to have reached its evolutionary peak, and it doesn't look it's going to be evolved any further. This is not due to problems inherent in the language itself. Instead it seems the problem lies with Java's stewards (Sun and the JCP) and their unwillingness to evolve the language to keep it current and modern, and more importantly the goal to keep backward compatibility at all costs. Not just Sun, but also it seems the large corporations with correspondingly large investments in Java like IBM and Oracle aren't exactly chomping at the bit to improve Java. I don't even know if they think it even needs improvement at all. So really, the ultra-conservative attitude towards change and evolution is the problem with Java from my admittedly limited view of things.

That's why I don't hate Java. But, I do hate the way it has been treated by the people charged with improving it. It is clear many in the Java community want things like closures and a native property syntax but instead we got Project Coin. This, to me, is sad really. It is a shame that things like closures and native properties were not addressed in Java/JDK/whatever-it-is-called 7.

Why Not?

I want to know why Java can't be improved. We have concrete examples that it is possible to change a major language in major ways. Even in ways that break backward compatibility in order to evolve and improve. Out with the old, in with the new. Microsoft with C# showed that you can successfully evolve a language over time in major ways. For example C# has always had a property syntax but it now also has many features found in dynamically typed and functional languages such as type inference and, effectively, closures. With LINQ it introduced functional concepts. When C# added generics they did it correctly and retained the type information in the compiled IL, whereas Java used type-erasure and simply dropped the types from the compiled bytecode. There is a great irony here: though C# began life about five or six years after Java, it not only has caught up but has surpassed Java in most if not all ways, and has continued to evolve while Java has become stagnant.

C# is not the only example. Python 3 is a major overhaul of the Python language, and it introduced breaking changes that are not backwards compatible. I believe they provide a migration tool to assist you should you want to move from the 2.x series to version 3 and beyond. Microsoft has done this kind of thing as well. I remember when they made Visual Basic conform to the .NET platform and introduced some rather gut wrenching (for VB developers anyway) changes, and they also provided a tool to aid the transition. One more recent example is Objective-C which has experienced a resurgence in importance mainly because of the iPhone. Objective-C has been around longer than all of Java, C#, Ruby, Python, etc. since the 1980s. Apple has made improvements to Objective-C and it now sports a way to define and synthesize properties and most recently added blocks (effectively closures). If a language that pre-dates Java (Python also pre-dates Java by the way) can evolve, I just don't get why Java can't.

While it is certainly possible to remain on older versions of software, forcing yourself to upgrade can be a Good Thing, because it ensures you don't get the "COBOL Syndrome" where you end up with nothing but binaries that have to run on a specific hardware platform forever and you are trapped until you rewrite or you go out of business. The other side of this, of course, is that organizations don't have infinite time, money, and resources to update every single application. Sometimes this too can be good, because it forces you to triage older systems, and possibly consolidate or outright eliminate them if they have outlived their usefulness. In order to facilitate large transitions, I believe it is very important to use tools that help automate the upgrade process, e.g. tools that analyze code and fix it if possible (reporting all changes in a log) and which provide warnings and guidance when a simple fix isn't possible.

The JVM Platform

Before I get into the changes I'd make to Java to make it not feel like I'm developing with a straightjacket on while having to type masses of unnecessary boilerplate code, I want to say that I think the JVM is a great place to be. Obviously the JVM itself facilitates developing all kinds of languages as evidenced by the huge number of languages that run on the JVM. The most popular ones and most interesting ones these days are probably JRuby, Scala, Groovy, and Clojure though there are probably hundreds more. So I suppose you could make an argument that Java doesn't need to evolve any more because we can simply use a more modern language that runs on the JVM.

The main problem I have with that argument is simply that there is already a ton of Java code out there, and there are many organizations who are simply not going to allow other JVM-based languages; they're going to stick with Java for the long haul, right or wrong. This means there is a good chance that even if you can manage convince someone to try writing that shiny new web app using Scala and its Lift framework, JRuby on Rails, Grails, or Clojure, chances are at some point you'll also need to maintain or enhance existing large Java codebases. Wouldn't you like to be able to first upgrade to a version of Java that has closures, native property syntax, method/property handles, etc?

Next I'll choose what would be my top three choices to make Java much better immediately.

Top Three Java Improvements

If given the chance to change just three things about Java to make it better, I would choose these:

  • Remove checked exceptions
  • Add closures
  • Add formal property support

I think these three changes along would make coding in Java much, much better. Let's see how.

Remove Checked Exceptions

By removing checked exceptions you eliminate a ton of boilerplate try/catch clauses that do nothing except log a message, wrap and re-throw as a RuntimeException, pollute the API with throws clauses all over the place, or worst of all empty catch blocks that can cause very subtle and evil bugs. With unchecked exceptions, developers still have the option to catch exceptions that they can actually handle. It would be interesting to see how many times in a typical Java codebase people actually handle exceptions and do something at the point of exception, or whether they simply punt it away for the caller to handle, who in turn also punts, and so forth all the way up the call stack until some global handler catches it or the program crashes. If I were a betting man, I'd bet a lot of money that for most applications, developers punt the vast majority of the time. So why force people to handle something they cannot possible handle?

Add Closures

I specifically listed removing checked exceptions first, because to me it is the first step to being able to have a closure/block syntax that isn't totally horrendous. If you remove checked exceptions, then adding closures would seem to be much easier since you don't need to worry at all about what exceptions could possibly be thrown and there is obviously no need to declare exceptions. Closures/blocks would lead to better ability to handle collections, for example as in Groovy but in Java you would still have types (note I'm also using a literal property syntax here):

// Find all people whose last name is "Smith"
List<Person> peeps = people.findAll { Person person -> person.lastName.equals("Smith");   } 

or
// Create a list of names by projecting the name property of a bunch of Person objects
List<String> names = people.collect { Person person -> person.name; }

Not quite as clean as Groovy but still much better than the for loops that would traditionally be required (or trying to shoehorn functional-style into Java using the Jakarta Commons Collections or Google Collections). Removal of checked exceptions would allow, as mentioned earlier, the block syntax to not have to deal with declaring exceptions all over the place. Having to declare checked exceptions in blocks makes the syntax worse instead of better, at least when I saw the various closure proposals for Java/JDK/whatever 7 which did not get included. Requiring types in the blocks is still annoying, especially once you get used to Ruby and Groovy, but it would be passable.

Native Property Syntax

The third change should do essentially what Groovy for properties does but should introduce a "property" keyword (i.e. don't rely on whether someone accidentally put an access modifier in there as Groovy does). The syntax could be very clean:

property String firstName;
property String lastName;
property Date dateOfBirth;

The compiler could automatically generate the appropriate getter/setter for you like Groovy does. This obviates the need to manually code the getter/setter. Like Groovy you should be able to override either or both. It de-clutters code enormously and removes a ton of lines of silly getter/setter code (plus JavaDocs if you are actually still writing them for every get/set method). Then you could reference properties as you would expect: person.name is the "getter" and person.name = "Fred" is the "setter." Much cleaner syntax, way less boilerplate code. By the way, if someone used the word "property" in their code, i.e. as a variable name, it is just not that difficult to rename refactor, especially with all the advanced IDEs in the Java community that do this kind of thing in their sleep.

Lots of other things could certainly be done, but if just these three were done I think Java would be much better off, and maybe it would even come into the 21st century like Objective-C. (See the very long but very good Ars Technica Snow Leopard review for information on Objective-C's new blocks feature.)

Dessert Improvements

If (as I suspect they certainly will :-) ) Sun/Oracle/whoever takes my suggestions and makes these changes and improves Java, then I'm sure they'll want to add in a few more for dessert. After the main course which removes checked exceptions, adds closures, and adds native property support, dessert includes the following:

  • Remove type-erasure and clean up generics
  • Add property/method handles
  • String interpolation
  • Type inference
  • Remove "new" keyword
Clean Up Generics

Generics should simply not remove type information when compiled. If you're going to have generics in the first place, do it correctly and stop worrying about backward compatibility. Keep type information in the bytecode, allow reflection on it, and allow me to instantiate a "new T()" where T is some type passed into a factory method, for example. I think an improved generics implementation could basically copy the way C# does it and be done.

Property/Method Handles

Property/method handles would allow you to reference a property or method directly. They would make code that now must use strings strongly typed and refactoring-safe (IDEs like IntelliJ already know how to search in text and strings but can never be perfect) much nicer. For example, a particular pet peeve of mine and I'm sure a lot of other developers is writing Criteria queries in Hibernate. You are forced to reference properties as simple strings. If the lastName property is changed to surname then you better make sure to catch all the places the String "lastName" is referenced. So you could replace code like this:

session.createCriteria(Person.class)
        .add(Restrictions.eq("lastName", "Smith")
        .addOrder(Order.asc("firstName")
        .list();

with this using method/property handles:

session.createCriteria(Person.class)
        .add(Restrictions.eq(Person.lastName, "Smith")
        .addOrder(Order.asc(Person.firstName)
        .list();

Now the code is strongly-typed and refactoring-safe. JPA 2.0 tries mightily to overcome having strings in the new criteria query API with its metamodel. But I find it pretty much appalling to even look at, what with having to create or code-generate a separate "metamodel" class which you reference like "_Person.lastName" or some similar awful way. This metamodel class lives only to represent properties on your real model object for the sole purpose of making JPA 2.0 criteria queries strongly typed. It just isn't worth it and is total overkill. In fact, it reminds me of the bad-old days of rampant over-engineering in Java (which apparently is still alive and well in many circles but I try to avoid it as best I can). The right thing is to fix the language, not to invent something that adds yet more boilerplate and more complexity to an already overcomplicated ecosystem.

Method handles could also be used to make calling methods using reflection much cleaner than it currently is, among other things. Similarly it would make accessing properties via reflection easier and cleaner. And with only unchecked exceptions you would not need to catch the four or five kinds of exceptions reflective code can throw.

String Interpolation

String interpolation is like the sorbet that you get at fancy restaurants to cleanse your palate. This would seem to be a no-brainer to add. You could make code like:

log.error("The object of type  ["
    + foo.getClass().getName()
    + "] and identifier ["
    + foo.getId()
    + "] does not exist.", cause);

turn into this much more palatable version (using the native property syntax I mentioned earlier):

log.error("The object of type [${foo.class.name}] and identifier [${foo.id}] does not exist.", cause);

Type Inference

I'd also suggest adding type inference, if only for local variables like C# does. Why do we have to repeat ourselves? Instead of writing:

Person person = new Person();

why can't we just write:

var person = new Person();

I have to believe the compiler and all the tools are smart enough to infer the type from the "new Person()". Especially since other strongly-typed JVM languages like Scala do exactly this kind of thing.

Elminate "new"

Last but not least, and actually not the last thing I can think of but definitely the last I'm writing about here, let's get rid of the "new" keyword and either go with Ruby's new method or Python's constructor syntax, like so:

// Ruby-like new method
var person = Person.new()

// or Python-like construction
var person = Person()

This one came to me recently after hearing Bruce Eckel give an excellent talk on language evolution and archaeology. He had a ton of really interesting examples of why things are they way they are, and how Java and other languages like C++ evolved from C. One example was the reason for "new" in Java. In C++ you can allocate objects on the stack or the heap, so there is a stack-based constructor syntax that does not use "new" while the heap-based constructor syntax uses the "new" operator. Even though Java only has heap-based object allocation, it retained the "new" keyword which is not only boilerplate code but also makes the entire process of object construction pretty much immutable: you cannot change anything about it nor can you easily add hooks into the object creation process.

I am not an expert at all in the low-level details, and Bruce obviously knows what he is talking about way more than I do, but I can say that I believe the Ruby and Python syntaxes are not only nicer but more internally consistent, especially in the Ruby case because there is no special magic or sauce going on. In Ruby, new is just a method, on a class, just like everything else.

Conclusion to this Way Too Long Blog Entry

I did not actually set out to write a blog whose length is worthy of a Ted Neward blog. It just turned out that way. (And I do in fact like reading Ted's long blogs!) Plus, I found out that speculative fiction can be pretty fun to write, since I don't think pretty much any of these things are going to make it into Java anytime soon, if ever, and I'm sure there are lots of people in the Java world who hate things like Ruby won't agree anyway.

From http://www.nearinfinity.com/blogs/scott_leberknight

Published at DZone with permission of Scott Leberknight, author and DZone MVB.

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

Tags:

Comments

Casper Bang replied on Tue, 2009/11/10 - 3:04am

Interesting blog post. I agree with pretty much everything. The problem as I see it is Sun's painfull devotion to backwards compatability, lack of vision and focus. I mean, we've never seen as many JSR's being dropped and resources going from Java - lately in Sun's futile attempt at arm-wrestling with Adobe [http://www.google.com/trends?q=flex%2C+silverlight%2Cjavafx].

Gervais Blaise replied on Tue, 2009/11/10 - 3:26am

I haven't read all because I don't want to read one more time someone who say that Java is in a sleeping state. Yes of course, core Java is sleeping and the new JDK will come with "minor" improvements that are more syntax sugar than real improvments.

But we are developers, we don't want to reinvent the wheel but we can improve it instead of criticising her.

Since two years I have heard and read many people about closures. Will closures save the world ? I don't think. We can write good apps without closures.

You said that you want to remove checked exceptions but personnaly, I think that checked exceptions are a good thing. If you don't like checked exceptions, you can write unchecked wrappers around checked..
There is many other things that developpers want but don't forget that Java is a strongly typed language and all the conventions like beans help us to write generic applications.

Of course there are many things that can be improved but changing all of these things will result in a hell were we have to throw away our favorite IDE and return to simple text editor and "javac" while IDES are being rewrited and powerfull frameworks are adapted for the new conventions.

Thomas Mueller replied on Tue, 2009/11/10 - 3:30am

  • Improve Java
See JDK 7 Project Coin
  • Remove checked exceptions
I agree. As a start, new libraries should not use checked exceptions.
  • Add closures
Use Scala :-)
  • Add formal property support
There are two options: use Scala, or use a workaround as in JaQu.

Gabor Farkas replied on Tue, 2009/11/10 - 3:39am

I don't think that the language is the most important part about java. In an enterprise development the features of the actual language are usually the least important things when choosing a platform. A well designed web development framework, for example, can save a way more of time than whether you have closures or even generics. Of course, coding without these language constructs can be quite inconvenient - but the extra time programmers spend because they have to code without these language features is usally really neglible. (Nb: annotations in java 5 are a basis of many EE frameworks I love to use - that was really missing earlier).

In short, I think it will be the enterprise framework and platforms built on java that will make it used years from now, no matter how the language itself is improved.

Nicolas Frankel replied on Tue, 2009/11/10 - 4:21am in response to: Gabor Farkas

Completely agree with you. I'm always scared to read articles that just want another language feature, and scoff at backward compatibility like it's an evil thing.

People, wake up! Customers don't care about closures or whatever but care they will have to redevelop their +200 applications in order to integrate a new version of the language. Are we really living in the same world?

Mark Thornton replied on Tue, 2009/11/10 - 4:26am

You can't adopt the c# 'solution' to generics without throwing away variance and that would break a lot of existing code. So reifying generics is stuck in the too hard basket.

Endre Varga replied on Tue, 2009/11/10 - 4:58am

Why removal of checked exceptions again?

Guys, have you ever considered that the problem is not with the enforcement of exception handling (namely, declaring throwing checked exceptions) but with the handling?

I am pretty much against removing checked exceptions, but instead we should improve exception handling syntax. There are a few common scenarios, that we use:

  • catch, log, swallow
  • catch, log, rethrow
  • catch, translate, rethrow
  • catch, handle, recover
Now the problem is, that the good old "try" keyword is optimized for the fourth scenario. What I would like to see, is that if my class only translates and rethrows (or logs and rethrows; or swallows) exceptions, then I could declare it in one place in the class body and that would apply for every method. That would remove clutter.

 

Also, there should be some support for exception chain matching and transformation. Many libraries just add some text to the Exception, but do not try to improve the error reporting by using the available context information like exceptions down the chain.

Armin Ehrenreich replied on Tue, 2009/11/10 - 4:59am

The Java language is pretty handy for what I use it. If you talk to C# developers most of them say that they lost overview of all those redundant language features added to that language lately and that it gets more and more complicated to understand C# code written by other persons. I am really relieved that Java has not yet turned in such a mess. Remember C++, when each company had its guidelines what features of the language must not be used?

It is no progress to turn Java in a scripting language. Why properties? In my opinion they break encapsulation or are simply the a task for the editor. And there is JavaFX

I like the idea of checked exceptions. They remind the programmer to maintain a reputable programming style (and deal with exceptions). Of course you have at least to log them and not do simply nothing. But when you do so, you (and your code reviewer) know at least that you work sloppy. No example for writing maintainable code.

And closures are a chapter on their own. They represent simply a programming style of the season and came into fashion together with Ruby. But Ruby is build around them, Java not. Java had the clumsy inner classes as a kind of replacement. In the CICE proposal a relatively simple suggestion was made to simplify this syntax. But that was not enough for the proponents of closures. They wanted to turn Java in a functional language, they wanted to define their own control structures and came up with the BGGA proposal that results in code that is very hard to understand for the average Java programmer. That would destroy Java as a handy, simple tool for writing maintainable code and put it in competition to languages like Scala. And that without need, just to follow the latest hype!. Please don't call that progress or "Java is dead" or something. I strongly think, that people who want to do functional programming should use Scala. A very elegant language; lets observe how long the functional hype will last. And lets not forget there is also Groovy available.

Endre Varga replied on Tue, 2009/11/10 - 5:12am

"pollute the API with throws clauses all over the place"

"Pollute"? Proper error handling is "pollution"? Exceptions should be not the exception. As in an ideal world every class should have a factory, in an ideal world every interface should have its own Exception. I cannot simply understand, that people who strive for high test coverage accept the sloppy practice of not handling errors properly

"So why force people to handle something they cannot possible handle?"

Probably to add more context information in the Exception, so debugging later would be easier? Again, people could be downright anal in their testing practices, and yet, they refuse proper error handling. Error handling is not just, recovery, it is also diagnostics. Have you ever used a parser that simply throws Exceptions and does not try to figure out what was wrong?

Chris Kent replied on Tue, 2009/11/10 - 5:43am

I agree 100%.  If it were an option to switch to Clojure or Scala I'd have given up Java long ago.  Unfortunately those of us who aren't running our own startup don't have that option and are constrained to use the language our employers choose.  It would be good if that language weren't frozen in time and could evolve with (or at least behind) the current state of the art.

It seems obvious to me that checked exceptions are a failed experiment.  Many of the features that Java first brought into the mainstream have been copied by other languages.  Why not checked exceptions?  If checked exceptions had succeeded in making Java developers handle exceptions properly then I'd accept the boilerplate they introduce.  But I don't think anyone can claim that.  Exception handling in most Java codebases I've worked on is a mess.  Bad programmers will find a way to write bad code, good programmers are good programmers whatever.  Checked exceptions don't change that.

Endre Varga replied on Tue, 2009/11/10 - 5:52am in response to: Chris Kent

An interface should enforce what kind of exceptions their implementations could throw. I cannot imagine any other option. If you use Depenency Injection and got a class then you cannot know what exceptions will throw, or future implementations could throw. This is solved if you must declare Exceptions in the interface. The implementations then translate their internal exceptions to this declared one. Without this, you do not have a chance, even if you have a recovery plan.

One example is, when you have a class, that reads some object from a source. The source is injected, and can be a database, network, file, etc. Without agreement on a common higher level exception there is no chance to catch all possible relevant exceptions, and therefore you cannot implement your recovery code (which could be providing the object from cache, and give a warning message that the information is stale).

Osvaldo Doederlein replied on Tue, 2009/11/10 - 6:34am in response to: Endre Varga

Agreed; checked exceptions are a great feature and removing it is a stupid suggestion even if you don't like that feature... the real fix is making it easier. It's very unfortunate that the enhancements to exception handling (multi-catch and smart rethrow) failed to make it in Project Coin. At least we're going to have ARM, which at least greatly simplifies try/finally blocks used for resource management.

Armin Ehrenreich replied on Tue, 2009/11/10 - 7:07am in response to: Chris Kent

It seems obvious to me that functional programming is a failed experiment. Functional languages (Lisp) are around since forever and never made it to the mainstream programming (just try to describe e.g. tree structures or graphs in Lisp). So good luck when switching to Clojure for your day to day programming but don't sell this as a major deficiency of Java. And I don't buy the argument that millions of Java programmers have to change just to trick your management. If you can not convince your management to use e.g. Scala or Groovy for certain projects why then the whole rest of the world has to be forced to make Java like Scala or Ruby.

Marcos Antonio replied on Tue, 2009/11/10 - 7:31am

Among these features formal property support is the one I would like to see the most in Java. I really can't understand why it isn't already there.

Rogerio Liesenfeld replied on Tue, 2009/11/10 - 9:24am

So, you want Sun to give you a language which will:
  • Remove checked exceptions
  • Add closures
  • Add formal property support
  • Remove type-erasure and clean up generics
  • Add property/method handles
  • String interpolation
  • Type inference
  • Remove "new" keyword

Well, all that (and more) is exactly what Sun is doing! Except that not for the Java language, but for JavaFX Script. Have a look at the Java FX issue tracker for the evidence: they are closing issues every day, and JavaFX 1.3 is due to be out in the next few months.

Cedric Beust replied on Tue, 2009/11/10 - 11:12am

> So why force people to handle something they cannot possible handle?

 You have a deep misunderstanding of checked exceptions if you think that's how they work.

If you can't handle a checked exception, you just declare it in your `throws` clause.  That's it.

The strength of checked exceptions is that they force you to think about error handling. Runtime exceptions are much more dangerous in the sense that they give callers the illusion that they can ignore errors.

In my experience, code that correctly handles checked exceptions has always been more robust than software that relies on frameworks that completely eschew checked exceptions.

--
Cedric

 

 

Stefano Girotti replied on Tue, 2009/11/10 - 11:24am

No big surprise, the author is using Groov/Grails...

Almost all new java features he's talking about are avaible in groovy with almost 0 problem of backward compatibility.... So why change the language tomorrow when you can use groovy today?

 Just My 2 cent

Mark Haniford replied on Tue, 2009/11/10 - 11:28am

It's doubtful that at this stage of the game Java will be changed in any more substantial ways.  If it were to happen, then it would have happened in Java 7.

The good news is that because of Java's stagnation, it gives great incentive for outside developers to innovate on a language that isn't Java.  Unfortunately, I don't think Scala or Groovy in their current forms are replacements for Java (the language) for mainstream developers.

Offtopic, but I believe when Sun made the decision to open source Java a few years ago, that they saw the writing on the wall regarding the long-term viability of the company as an independent entity, and wanted to make sure that nobody could close it up.

Stefan Langer replied on Tue, 2009/11/10 - 12:15pm

I'm not going to comment on the blog entry in itself but I have to say something about the comments that are added.

@Cedric: If you can't handle an Exception then it shouldn't be a checked exception. What is the purpose of makeing somebody catch something that he can only porpagate up the call stack? The best thing to do with Exceptions is to make the code fail in a safe manner and inform somebody of the failure so that somebody can do somehting proper about it or if you have the ability fire up the debugger and let somebody correct the error. CheckedException just produce boilerplate code. If you think it important to inform people of your interface throwing a certain exception then by all means do so with the Documentation for that interface.
Anybody who ever had to change exception throwing in an existing code base knows what I'm talking about. Especially when it comes to public APIs. Just think about the close stream nightmare checked exception have brought upon the java world.

@Armin Ehrenreich: Functional programming languages are not a hype and some of them have actually produced programs that are a lot more robust then anything written in Java. Some of the most traffic intensive and high availability software was written in functional ways. Take a look at Erlang and then repeat what you were saying.
I think that we will see more functional stuff coming up once we actually start programming in a concurrent way cause side effects are the root of a lot of problems encountered in a truly parallel world.
And your talk about closures is utter bs and the way you talk about them I'm sure you have never used them properly. Especially in combination with higher order functions they become a superior tool for creating abstractions. Something you simply cannot do with the current Java stuff without producing a lot of boilerplate and therefor unreadable code. Thank god there are a lot of smart people out there that produce libraries that hide all this complexity behind a clean API (most of the time).

Just because Average Joe is just too dumb to use it and is not willing to learn is not a good reason to reject something. I don't even want to think where modern medicine would be if they had an attitude like we do. (Average Joe should be capable of removing an appendix...) In fact I believe this is one of the major problems that is keeping our profession from reaching a mature state.
In my eyes anybody who is professional and willing ot learn can grasp the concept behind closures.

Oh and before you start again with inner classes please try to give me currying with inner classes...

Jeff Martin replied on Tue, 2009/11/10 - 12:29pm

We Java devs are so code centric - there isn't a single language feature that is going to save us. The answer is that we need our own Flash Designer, FlexBuilder, Silverlight ExpressionBuilder. Here's a tool that lets us code Java from the top floor instead of the basement:


DataBox

Veera Sundar replied on Tue, 2009/11/10 - 12:24pm

I agree on pretty much all the points except the 'new' thing. I would like to prefer 'new' keyword instead of a new method the or the constructor. The method way of creating objects may be used for creating singletons. That way it is more meaningful like MyObj.getInstance(), instead of new MyOBJ().

Loren Kratzke replied on Tue, 2009/11/10 - 12:52pm in response to: Cedric Beust

You have a deep misunderstanding of checked exceptions if you think that's how they work.

If you can't handle a checked exception, you just declare it in your `throws` clause.  That's it.

 Well spoken. Every time I hear developers whine about checked exceptions I wonder if they are inexperienced, careless, or simply do not understand the role that checked exceptions play in quality software. I shudder to think of the resource leaks, undefined behaviors, and generally crappy user experiences that these people generate now, and would generate if checked exceptions disappeared.

 

Cedric Beust replied on Tue, 2009/11/10 - 1:00pm

Stefan:

> If you can't handle an Exception then it shouldn't be a checked exception.

You are mixing up two different things here: the sender and the receiver of the exception.  The sender is the one that decides whether the exception is checked or not. The receiver can do nothing about that decision.

When you write code that can fail, you need to decide if you should throw a checked or runtime exception. The rule of thumb is: if someone, somewhere might be able to do something about this exception, then it should be checked. On the other hand, if that exception is pretty much a guarantee that you are now in an unstable state, make it a runtime exception.

FileNotFoundException is a good example: maybe you, at your stack frame level, don't know what to do if you can't find that file, but it's likely that one of your callers will. You don't know how they will use that information (logging? showing a dialog to the use?), but it's definitely recoverable, so it should be a checked exception.

> If you think it important to inform people of your interface throwing a certain exception then by all means do so with the Documentation for that interface.

A check enforced by the compiler will always beat one written in comments.

I'm seriously puzzled by your position since you are now saying that this information is important but that it should be captured in the documentation...  This doesn't make sense to me: either it's important and you should have the compiler enforce it or it's not important and there is little point in mentioning it anywhere.

> What is the purpose of makeing somebody catch something that he can only porpagate up the call stack?

The purpose is that a lot of errors are just not meant to be handled in the stack frame that they are happening at, but now you are talking about something totally different (basically pitting exceptions against result codes) since your remark has nothing to do with the runtime/checked exception debate.

--
Cedric

JeffS replied on Tue, 2009/11/10 - 1:01pm

Java the language is great as it is.  People can understand it, write good, clean, maintainable and extensible object oriented code with it, and people coming and going in the dev team can understand what the code is doing.

 That is very very important, and usually trumps any arguable benefits new language features might bring.

Lately, Closures are the darlings of the developer blogosphre.  People seemed enamored in the reduction in overall boilder plate code the functional paradigm can bring.

But that is a double edged sword.  The more concise code closures bring can bring also make the code a whole lot harder to understand, particularly to the next person who has to maintain the code, and may not necessarily understand the functional paradigm.

Also, typing is easy.  I don't mind typing code.  It does not make my programming life harder, or require extra mental energy.

In other words, the 5 to 10 lines of standard Java code (which might involve a loop, or extended class ( or whatever), which could conceivably be reduced to a line or two of closure code,  is easier to deal with than the cryptic closure code (as elegant and concise it might be).  It's easier to undertand, and thus maintain, the legacy Java code than it is for the "fashionable" closure code.

I've also decided that I rather like Java's verbosity, whereas I used to hate it.  Again, typing is easy, but a little verbosity makes things really easy to read and understand.

I've recently been reading "C# in Depth".  This is not a beginner's tutorial, but really focuses on new features in C#2 and C#3 (as well as delegates in C# 1).  There is a lot of "latest and greatest" language features in C#, and as I'm going through the code exambles, and reading the author's explanations, I get excited.  I think "that's pretty cool" (when looking at delegates, generics, properties, lambdas, LINQ, ect), it really makes the code more elegant and concise.  And I think"gee, that really puts Java behind".  But then I re-examine the the code snippets, and realize that it is indeed harder to understand and tell just what it's doing. 

This is particularly relevant in the first chapter (an overview of features), where he goes through a code example in C#1, then modifies it for latest features of C#2, then modifies it again for latest features of C#3.  In each case, the code gets more elegant and concise.  But also in each case, the code gets harder to understand, and grok exactly what it's doing.  In all honesty, the first C#1 example is the easiest to deal with, even though it's more verbose.

Then I also ask myself "just how many .Net devs actually utilize these latest goodies in practice".  Anecdotal evidence says not many.  Both in my organization and organizations my company deals with, most people using .Net are quite slow to upgrade to the latest version of .Net.  And in my conversations with .Net devs, I quite often get a "huh?" when I mention stuff like lambdas and LINQ.  Heck, people are still kind of grappling with delegates.

 Elite developers, like typically the ones that frequent forums like Javalobby ;-) , tend to understand stuff like closures or the functional paradigm.  But there are many people who don't even know what closures are (or the functional paradigm), much less understand them.  

But that's not to say that just because the average dev doesn't grok it yet, we shouldn't move towards it.  After all, the OO paradigm wasn't always the main way of going about things.  It was slow for getting everyone up to speed on OOP.  Only in recent years do we consistently get devs who fully understand OOP.  But the benefits of OOP are pretty strong, and worth the effort.  Thing is, I don't get that with closures/functional.  I've tried several tutorials, read books, and compiled sample code, and I've yet to get that big "Ah-Ha!".  

So, at this point, I'll take Java's stability, ease of use, maintainability and extensibility, and backwards compatibility.  For those that want the latest goodies on the JVM, there's Scala, Groovy, and JRuby.

 

Otengi Miloskov replied on Tue, 2009/11/10 - 1:15pm

Java is not dead and it will take some time to get dead. But The author have a point and it is that Java is becoming the next Cobol. Just the big corporations that are lazy or spend millions to migrate code they will keep Java. The world is moving to the dynamic languages for example Python or PHP are very popular for new development. Even C++ is imporoving see C++0x with type inference and closures etc.

If somebody does not do something soon with Java, say good bye to it, It is getting to late and SUN lost focus and managment for Java. Java future is uncertain.

By the way I dont see the JVM also in a good position. I find buggy the JVM/JDK implementation for FreeBSD servers so even my Scala code could not work in the future on those servers so it is that the JVM is not WORA!.

Maybe for me is better to check another solution as for example PHP I can compile it where it is a C compiler so it means any platform or OS.

Java/JVM promises are broken.

Loren Kratzke replied on Tue, 2009/11/10 - 1:17pm in response to: Stefan Langer

Stefan said, " If you can't handle an Exception then it shouldn't be a checked exception."

That is crap. Don't you understand that if you are 20 calls deep in the stack that perhaps the transaction that will be impacted by the checked exception might be 10 calls up the stack? There may be many resources that need to be closed along the way, flags to be set, alternate execution paths to be taken, and when the exception is finally handled, perhaps it is not the end of the world, or perhaps it is.

You (as a commenter in this thread) have no way of knowing about code you personally have never seen and will never see so I find it intersting that you (or anyone) can make such a broad sweeping declaration such as you did based upon abstract and unknowable information.

Cedric Beust replied on Tue, 2009/11/10 - 2:06pm in response to: JeffS

JeffS,

Couldn't agree with you more.

 I love to play with advanced concepts as displayed in Ruby, Clojure, C#, etc... but when it comes to writing production code, Java remains extremely readable and fantastically maintainable.  I can come back to Java code I wrote six months ago and find my bearings right away.

It's much harder with Ruby and other advanced languages.

 

Endre Varga replied on Tue, 2009/11/10 - 2:10pm in response to: Loren Kratzke

You are not forced to handle anything. What you are forced is to decide, what should happen. Also I have to reiterate my previous comment, handling does not necessarily means recovering. It could be translation between different abstraction levels, logging, adding context information, analyzing casue exceptions, etc.

My impression is that people do not hate checked exceptions, but they hate the exception concept. They do not like checked exceptions because they make exceptions visible. By dropping checked exceptions, they can finally forget those inconventent nasties.

Loren Kratzke replied on Tue, 2009/11/10 - 4:57pm in response to: Endre Varga

I think that getting rid of checked exceptions is like getting rid of stop signs.

Personally I have come to rely upon stop signs for my safety. Sure, sometimes I stop at one when clearly there is no other car coming and I have to stop anyway, but that is a small price to pay for not getting t-boned when I least expect it.

 

Anders Forsgren replied on Tue, 2009/11/10 - 4:57pm

Begin rant

1. Exceptions:

Checked exceptions are clearly a double edged sword. The idea is great in theory. Less so in practice. I'd say the feature is more critizised in java than it is missed in C#. With better handling support (catch multiple types of exceptions etc.) it could be less awkward to work with. Bottom line: checked exceptions not one of the really big productivity problems in java. The time one spends in java wrestling with exeptions in method signatures, or catching four different exceptions when creating ONE object through reflection, is perhaps comparable to the time spent backtracking what you wish had been checked exceptions in C#. 

2. Properties:

Properties are simply syntactic sugar. Sure, as some posters have pointed out, your IDE can create getters and setters for you, but still. If I create a class with 10 fields, it has around 15 lines of code. If the first thing I need to do to make that class usable is generate 20 methods, creating a class of perhaps around 100 lines of code, then that is just wrong. You have to be pretty conservative to not include it.

3. Closures/Functional concepts: 

One commenter said "functional programming is a failed experiment". Perhaps, as a general purpose tool it may be (even though "actual stuff" has been made with functional languages). But some features of funcational programming have become so mainstream that they have become must-have features of a modern day to day language. In java you often find yourself specifying object properties as strings, which kills compile time safety. It's wrong. Compared to compile-time checked queries like LINQ, all kinds of string-based queries (e.g. HLQ) feel dated.

4. Generics:

Type erasure is simply a bad idea. Having worked with java (pre-generics) for about 5 years before moving to C# for about 5yrs before coming back to java 1.6 I was chocked to see how miserably generics had been implemented in java. In .NET generics was added at the bytecode level, without breaking backwards compatibility (the generic list is a different class than the nongeneric list).  Javas generics provide no real compile time safety, and without the possibility to access the generic types in a generic class, it's half useless (whenever I see "SomeType.class" in code I always think that someone screwed up).

Bottom line: I totally agree with the author. Java is moving way too slow. You simply can't say that a language has matured "enough" to be a tool versatile enough to solve most problems. If it's not evolving its dying. And it is not enough to point at scala/groovy/jruby/javafxscript and say "feature x is here". I want feature x in my general purpose language I use every day. 

This can also be said about the platform/api:s, I mean just remove what has been deprecated forever! Clean up the date/time utilities! I don't care if all my datetime code from 2001 is broken, as long as it's sane once I fixed it.

End rant.

Comment viewing options

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