Disclaimer: my opinions on programming languages are based on intuition and casual observations more often than on deep knowledge and experience, so please take everything said below with a grain of salt.
I think Java is definitely the programming language and platform for most applications right now, be it server, desktop or mobile. C#/.NET is comparable and C# as a language may actually be a bit better when it comes to features, but as long as it’s controlled by Microsoft and at the same time Java is more open, less controlled, and the JRE has many implementations, most people and organizations will (or should) choose Java.
But Java is the general purpose language that can satisfy almost any requirements and scale in most directions (if not quite down to scripting).
However, Java has problems as well.
- Verbosity and boilerplate are perhaps the first things that come to mind, especially considering recent discussions in the blogosphere. Some other recent languages allow programs to be written with more fitting levels of abstraction — mostly because of features adopted from functional programming.
- The JCP has received some criticism recently and Sun seems to be behaving badly there in some cases. It may be that Sun is actually holding Java back in some ways.
- Java has great backwards compatibility, but I think it’s starting to get in the way of things. Don’t get me wrong — backwards compatibility is usually a really really great thing, but at some point it becomes gunk that prevents you from having a clearer picture of the current state of things and acts as conceptual baggage.
I’ll go into more detail about what my thoughts are on the backwards compatibility, but if you want to read more opinions on the other two points, you can follow the links I provided.
Personally, I think that even a very large code base should be refactored periodically to take advantage of new language features, better libraries and abstractions, new solutions to recurring problems, etc. I haven’t always been able to do this at work, but I actually enjoy doing it when I have the opportunity. This keeps the code base from sliding into a state where programmers think of it as legacy and eventually spaghetti that no one really wants to work on any more. Certainly, if a new version of Java broke any backwards compatibility, tools could be released with it and other measures taken to allow even the largest code bases to be safely and easily refactored to keep them current.
I think there is still little enough of the backwards compatibility cruft in Java that it’s not yet a huge pain for people, but it will only increase with time if something isn’t done about it (like actually removing deprecated stuff). A lot of improvements are still being made to Java and the JVM, some of the current proposals might benefit from being allowed to break compatibility. But in the end there is not much choice: Java can’t just become a different language by adding features on top of features and breaking old ones. Only small improvements, and maybe a few important larger ones, can be made. But it will never take Java to the same level as some newer languages.
The pessimist in me thinks that Java will remain in its current position for a long-long time and while people will increasingly be a little frustrated with the verbosity, boilerplate and accumulating cruft, everyone will just have to live with it and try to ignore the accidental complexity noise as much as they can.
The optimist in me thinks that in the next few years a new language (or languages) will arise that has roughly all the best features of Java and C# combined, functional features, cleaner syntax and abstractions, and without all the baggage. It must be purely open source and not in any way controlled by a single corporation, but should gather support from many corporations. It must present clear, manageable migration paths from Java and .NET. The first versions of this language should actually run on the JVM and/or CLR. Later versions can perhaps add a new virtual machine (with tools to ease migration), although I see no reason to think that the JVM isn’t already good enough.
And unless all progress stops, that language will not be the end of things either. If we’re lucky, it will last us 15-25 years before becoming an obsolete mess of backwards compatibility layers and wrong abstractions.
Before finding and falling in love with Scala, I was pretty sure that this (“next big”) language didn’t exist yet. Right now, I’m not so sure anymore. Scala could be it, but it does have its little weirdnesses that may keep it from mass acceptance. There is one thing I am certain of, though: the next big language has a lot to learn from Scala. It brings together the object oriented and functional paradigms with performance, nice syntax and static typing in a really amazing way, and I believe that any language which is to be used for multi-core systems programming must do the same. I think no one can go wrong by learning Scala today — what you learn will be useful even if Scala won’t be the language you will be using the most in the future.