This guy claims that Java is a dying language.
I think that's an optimistic assesment. I wish Java were a dying language. Instead, I predict that Java will be the COBOL of the 21st century- this arcane, but widely used language that will keep cropping up, again and again, in enterprise applications for the next fifty years. Someplace around the turn of the next century, there will be a renaissance of people needing to relearn it to replace/repair these applications.
Java is far harder to use than it needs to be. When the class library was designed, it was the first time a large-scale object oriented API was built into a language. There was a lot of backlash against that, believe it or not. People like me, coming from a C/C++ background were mistrustful of this (in retrospect, I can only wonder why!). We were used to managing our libraries as external links, and didn't want that stuff built into our languages.
So, Java's evolutionary response was to keep the class library at a low level. This made it so that huge amounts of code were needed to do simple tasks- but you could do those tasks in a million different ways. While we lost simplicity, we gained a good amount of flexibility.
Then came server side Java- J2EE. The class library strategy had proved a success, and now a bunch of very smart people set about using the same logic, coupled with strong OO decoupling principles, to design an enterprise application platform.
The result is a horrible mess. In a J2EE application, very little of what you write is Java code. Mostly, you rely on stubbed classes and JSPs to provide the framework, and gobs of XML configuration files to string it together. J2EE invented the role of the "Enterprise Architect"- someone whose sole job was to take all of these chunks of code and configuration and string them together.
Once again, there's a great deal of flexibility here- an extreme amount. But being flexible isn't always good. Let me give you an example:
Joebob writes an "Enterprise Java Bean"(EJB). This is a bunch of Java code that represents a piece of data. This EJB gets published with a "JNDI name"- basically, it goes into a folder path, something like: "ejb/data/MyBean". That information gets put into an XML config file that goes with the EJB library.
Then, Susiebob writes a JSP/Servlet application that's going to talk to that EJB, so in Susiebob's config file, she asks for (in her web config file) an EJB with this JNDI name: "ejb/beans/data/JoebobBean".
Wait a second! That's not the name Joebob gave it! That's okay though, because in the server configuration, we can set up a mapping that says: "when the web app wants 'ejb/beans/data/JoebobBean', give it the bean going by 'ejb/data/MyBean'".
This strong decoupling makes it trivial to swap out components in the future. So that's good. But it's a beast to maintain- three config file entries to simply load a class and use it?
A very common mistake in application design is being too flexible. The more flexible you try and make your application, the more work it is to use the application. Java is full of these mistakes in spades.
I have another beef with Java. Mainly in that colleges are turning to it as their defacto language for Computer Science programs. This is idiocy, and it does a disservice to the students.
Don't get me wrong, Java is great (although .NET is better) for teaching good Object Oriented design concepts. But Java isn't good (and .NET is worse) for teaching people how to think like a computer. It's impossible to truly understand the value of references and garbage collection if you don't understand pointers- and you learn pointers from C/C++ languages. You don't understand the value of OO if you haven't struggled through a moderately complex structured program.
The other problem- and I think this is a big one- is that we're teaching our CompSci students to be slaves of a single vendor. Sun makes Java. Microsoft makes .NET (oh, sure- there's open source .NET variants, and they see use. There are some open source JVMs as well. These projects are still exposed to sudden changes in the vendor's attitude.).
Imagine a musician that knows nothing about any instrument but the one they play. They might be an expert on the violin, but if they don't know at least something about the piano, they're going to have a hard time understanding music theory. If they don't know something about the violas and cellos, they aren't going to understand their role in the orchestra.
But let's go back to the piano. Anyone even moderately serious about music learns at least a little but about the piano keyboard. Why? Because it's this common standby instrument. It has a range from the low end to the high end of the orchestra. Composers use it to write out parts for every instrument. It's the least common denominator- all music theory grows from it.
Is there an analog in programming? There are several, actually. In the same way that the piano may be the base of Western music, there are other instruments that are tuned to different scales that form the base of other cultural music. Programming is the same way.
The core language you need as a programmer is C++. C++ is the piano of most mainstream programming languages. If you understand C++, Java and .NET follow naturally from it. C, its ancestor, also follows naturally from it. There's a whole family of languages that just drop off from C++.
Any serious programmer must know C++. But that isn't enough.
There are several families of programming language: Structured, Functional, Object Oriented and Logical. The boundaries aren't clean and clear between them, but there are rough areas.
C++ is so important because it touches on three of those four- it is Structured (procedures represent tasks), Functional (a function represents some calculation to be performed) and Object Oriented (there are objects, they are models real-world things and concepts). If you know C++, other Structured languages are easy to learn, as are other Object Oriented ones.
But there's an entire family of languages that are truly Functional languages. LISP is the big one- the "piano" of Functional languages. LISP is great for mathematical programs- it is the language closest to pure math (and hence, gets a lot of use in those circles). But for a programmer, knowing a little LISP makes it easier to work with a lot of more modern languages- JavaScript and Ruby, for example, are heavily influenced by functional languages. .NET's delegates are an attempt to bring the most powerful features of functional languages back into strong OO languages (C/C++ used "function pointers"). The article I linked above mentions adding closures to Java- closures come from LISP.
Logical languages are high-order languages- generally very abstract. PROLOG is the classic example. They're good for designing expert systems and AI research, and I haven't worked with any of them very much. I've learned to play classical music, blues and rock, but not so much jazz.
So, my ideal CS program would teach: LISP (or a derivative) and C++ for the intro and core classes. Then one of: Ruby, Perl, Python. Then, in senior year, it would get into vendor specific technologies- .NET, Java. Web application design, etc.