My big gripe, though, is that using Java is such a struggle and I am a senior developer with over 10 years of commercial experience in all kinds of languages and frameworks. I am not a big fan of PHP but I can see where it works well. I wouldn't write most of my code in C but for some things it has an elegant beauty. Java on the other hand seems to have the worst of most worlds rolled into one.
- The language itself has weird shortcomings, that could have been fixed, but haven't and which are a real pain for those of us who are used to C#. Having to declare or catch every exception is nonsense. On paper it sounds good but, in reality, it means that exceptions are taken for granted and everything put into large "catch all" blocks rather than the intention of making people treat errors deliberately. If I am parsing a string into a number and I have already validated the input, why do I have to bloat my code with error handling for InvalidFormatException.
- Trying to compare strings with == compiles OK but doesn't do what virtually every other language would do - a string comparison of the two strings. In Java, it compares objects which, in my experience is totally useless and just asking to cause errors - subtle ones! The same goes for other basic types and you can't even overload operators to overcome this.
- Lots of the core libraries seem unnecessarily verbose. Compare the default HttpClient usage with the Apache one. No comparison.
- Various inconsistent naming and casing for classes throughout the core libraries.
- C# has introduced var for an implied typed variable. If you use var something = new Class(), you know that var equates to Class and this makes declarations so much shorter and clearer. In Java, no such luck, some names, especially with generics end up causing a constructor call taking up a whole line.
- Performance is basically terrible for most scenarios - another difference between the theory (write once, run anywhere) and the reality (virtual platforms suck). At least .Net can be compiled to a more useable and much faster byte code. The fact that it can perform acceptably well is not an excuse. I can make anything run fast by massive optimising or lots of hardware but these things should be like that by default.
- Libraries, jars, source paths, class paths etc. Is a NIGHTMARE in Java. It's like extern "C" in the old days which said "you should find this at runtime but if not, blow up". Why? If I have the library added to a project, shouldn't it all just work? This has done my nut trying to get a custom SSL manager working which compiles fine and goes bang at runtime. This is further worsened in the Android world since Google have handicapped some of the basic Java libraries for various (presumably) security and performance reasons.
- Using the file system directories to mimic the package names is complete nuts and doesn't (in my opinion) really give you anything other than headaches. Adding jars (glorified zip files) doesn't really change this. If anything, jars make it even more confusing since you have to browse through them to find some of your classes.
- Separation of docs, classes and libraries is just stupid. Another problem that rears it's head when you are trying to browse docs or code when debugging.
- Trying to understand the toolchain is also very hard for newbies. JDKS, JREs, J2EE - nice abbreviations for geeks but not useful for people trying to enter the world of Java.
- It doesn't do much of any of it's design goals. It's cross platform is crappy, it's embedded use is almost non-existent since it is so heavy weight and all of the failed goals came with a cost of a poorly designed language that is hard to use.
- There are too many third-party libraries that are considered standard - very worrying for a framework provider. Apache web client instead of the Java one, Bouncy Castle instead of the encryption classes in javax.security and even a cut-down version for Android that looks the same but will fail (sometimes at runtime) for this reason.
- One class per file (except inner classes) is another pointless-ism. An IDE is perfectly capable of parsing all files under a directory and finding where all the classes live. If I have a bunch of small classes, do I really need these massive directories full of files when one file called messages.class would make more sense?
I think in it's purest sense - the basic language - is not that bad, it mostly looks like C# and C++ but with all the additional annoyances makes it worse than the alternatives. C# has been evolving and provided features that are very useful - although optional. Using var for types you don't care about, (since you might just dump them in a data table for instance), linq for SET based data manipulation makes some functionality so much briefer (a foreach loop on one line which reads really well) and libraries which are not just maintained in one place, for consistency, but which have also integrated work that others have done such as DotNetOpenAuth.
To me, the ONLY reason I use Java is because I have to. I think in every way, C# and probably other languages are superior (most other languages are not exactly equivalent so this is harder to judge).
If Java died, I wouldn't cry!