Java is a little more difficult to practically use because it lacks most of that. Writing clean, maintainable code in Java is a lot harder (for me, at least) than the same in C# (or even in Scala, and Scala seems to lend itself naturally to writing a mess).
Also, let's be honest: the Java ecosystem is a mess in a lot of ways. One of the biggest pluses to the .NET world is that things tend to Just Work a lot more than in the Java world. Not that this is a huge deal (I work in Java, and handle it fine), but considerably more knowledge of the entire Java stack is often necessary than on .NET.
Writing maintainable code in Java, in 2011 anyway, should be a lot simpler than C# due to the shared knowledge within the Java community.
There are probably more books teaching how to write better code in Java than in C#. Even if the number of books in C# that taught better ways to code is approaching the Java counterpart, they are more likely to be newer books and not necessary preached by Microsoft.
As much as people don't like (or abusing) Spring and Dependency Injection concept, more Java projects are using it (with probably some amount of unit-testing) as opposed to C#.
When you look at Continuous Integration landscape, most of them came from Java.
I think Java is much easier to learn because the online documentation and community is superior to C#'s. I've also found that you can't understand the entire stack in .NET because that information is often just not available. You could argue that this makes .NET simpler, but we all know that software abstractions leak. When they do, it's nice to be able to peel the abstractions away.
Oh, and Scala naturally lends itself to writing maintainable and bug-free code.
> I think Java is much easier to learn because the online documentation and community is superior to C#'s.
This does not match my experience in the slightest. MSDN is leaps and bounds better than the Java documentation and the available resources at places like Stack Overflow tend, in my experience, to be of higher quality and quantity. In this I find that C#'s lack of favor as a pedagogical language works in the C# developer's favor: there's much more signal to much less noise.
> I've also found that you can't understand the entire stack in .NET because that information is often just not available.
This is simply not true. There is very, very little information that is not available about .NET (largely derived from either reading the specs or inspecting the IL) and essentially nothing unavailable about the .NET libraries thanks to Rotor (for legally safe inspection of certain libraries) and Reflector (which poisons you for Mono contribution, but is a fairly accepted practice).
> When they do, it's nice to be able to peel the abstractions away.
You can, trivially. It is an indictment of the largely ASP.NET-focused developers mentioned previously that they do not, but it is not a difficult task.
> Oh, and Scala naturally lends itself to writing maintainable and bug-free code.
After some confusion from this statement I entertained, if unwillingly, the thought that you are serious. Scala is no Perl with regard to its distaste for readable code, but it lends itself to ambiguous or stupid syntax (the inanity about "using what you like" for parens versus braces comes to mind as a minor quibble, the flinging of underscores throughout "idiomatic" code being a much greater one). To complicate matters, Scala's IDE support (even in IDEA, the best of a sorry lot) is horrifyingly bad. To what Scala lends itself, I have not yet been able to ascertain, but "maintainable" has surely not been an adjective I'd use. Partial credit for "bug-free" due to its tendency to encourage immutability, for which I am very thankful, but...only partial. I still have to read the byte-vomit.
The best compliment that I can pay to Scala is that it is better than Java--damning with very, very faint praise. I'm praying that Ceylon or Kotlin comes along and deals with this insanity in an adequate manner.
I guess you and I have opposite experiences with Java vs .NET, but I am relatively inexperienced in the .NET arena and am willing to concede the point here.
I am not however, inexperienced with Scala or with programming languages in general. I was very serious about Scala. There is nothing ambiguous or hard-to-understand about Scala's syntax. If a couple of underscores or inferred parenthesis throw you off then I seriously doubt your ability to read source code effectively.
I mean, really. Interchangeability of "()" and "{}" bothers you? Making them interchangeable, along with currying, lets you invoke higher order functions in a way that is much more natural looking than what you can do in C#. The Scala code often looks identical to Ruby's blocks, which, as a second witness, most people also find to be a far more pleasant syntax than the equivalent Python code..
Can you really not, when you see "call(_,_)", parse it in your head as its more verbose C#-like equivalent, "(a,b) => call(a,b)"? If you can read the C# version, there is no reason you can't just as easily read the Scala one.
Is it so hard for you to see that "list filter pred sum" is equivalent to list.filter(pred).sum()? Scala is actually simplifying and unifying the language with this rule. Whereas most languages handle arithmetic operators specially, Scala can treat 1 + 2 + 3 literally as 1.+(2).+(3), which means that + is just a normal method!. In this sense, Scala is simpler and easier to grok than almost any other mainstream language!
And, Scala's IDE support, which is supposed to be fairly good at this point, has no bearing on the topic of conversation. Finally, There is nothing exciting to hope for in Ceylon or Kotlin compared to Scala. It looks like, in terms of language advocacy, we are direct enemies!
Also, let's be honest: the Java ecosystem is a mess in a lot of ways. One of the biggest pluses to the .NET world is that things tend to Just Work a lot more than in the Java world. Not that this is a huge deal (I work in Java, and handle it fine), but considerably more knowledge of the entire Java stack is often necessary than on .NET.