and we're stuck with Java. Sad, I hope that bigger companies and startups choose to use .NET for the future. I love it but can't it seems like 80% of the big tech companies here are using java
I like the uniformity of Java language. I like the "inner class" feature that has to be manually emulated in C#. I also like that I can implement anonymous abstract class-interface ad hoc in Java. I wish that internal visibility in C# was tied to a namespace instead of assembly, like package visibility in Java. Method co-/contravariance in C# is tied to interfaces. I prefer it tied to individual methods, like in Java.
Yes, Java is more verbose to write, but it's easier to read. E.g., == in Java is always built-in equality. In C# it can be overloaded. Equality in C# is a mess (IEquatable, IEqualityComparer, the obscure way in which generic collections "discover" equality on the type...)
Then async/await hack and how it interoperates with Task infrastructure. It's so badly documented it's not even funny. An often-asked question is how to synchronously wait on an async method. The usual answer is "don't do it" like it solves anything. But async methods return a Task and the official examples for tasks tell you explicitly to use Wait() method to wait on a task. Which gives?? (A long story about synchronization context.) Java and Project Loom are doing it right, IMO.
Nullable reference types are another hack. I tried to convert a project to NRTs and gave up, reverted everything. I haven't seen a NRE in years :p NRTs introduce a lot of edge cases, with a lot of syntactic noise to cover them and still guarantees nothing (unlike a proper Optional type would).
Java takes longer time to push out features, but my impression is that when they do, the features are better thought out than their counter-parts in C#.
So right now the only thing I'm unhappy with in Java is streams not supporting checked exceptions. I actually _like_ them and Oracle should have invested in making them more usable in some way. What they did with streams kind of signals that they want to deprecate them in the long run. It's a missed innovation opportunity.
As a counter example: As someone that worked for years in .Net and started trying to develop some projects in the Java ecosystem... what a fucking mess.
Days of work to try and get projects to BUILD. Do I have to use Gradle, Maven, or something else? Which IDE to use? The IDE isn't working with whatever version of Gradle or Maven I'm using. Dependency hell. Restarting my IDE repeatedly, re-downloading dependencies, trawling through the horrible Maven site trying to work out what version of a certain dependency I need. Keeping massive amounts of notes because I'm sure in two weeks I'm going to forget which arcane command I need to keep my Java build environment working.
The horrible verbosity of Java making it way harder to read then C#. Realising that there's no standard equivalent of tasks and async and I have to work out which of the 10 3rd party implementations is the "good one" and then realising that the recommended one is again verbose, ugly, and more complex to write and understand than Tasks and Async in .Net.
Having to work out which Java runtime environment I need. Having to register on the Oracle website to download their runtime, then finding out that maybe an open source runtime is better, then finding out nothing is supported for ARM macs. Then realising that this runtime means my IDE ends up breaking. Multiply all these problems if you decide to write Scala instead.
The Java and JRE environment in general is a huge mess in comparison to Microsoft's .Net platform. .Net "just works." There is no confusion of how to build, what IDE to use, what package manager, everything works together seamlessly. I can get a new engineer setup to write and deploy .Net in minutes. Our company literally has to have three engineers gather around someone's computer for half a day to get a Java or Scala environment working correctly and often it ends up working seemingly by magic, i.e. we can't deterministically understand why it ended up working.
Java was actually my first programming language in college but Oracle has radically mismanaged it. I would not recommend it unless you really need some specific library that only exists in the Java ecosystem.
Oracle has done wonders for Java. It has kept it from languishing like it was under Sun.
Most of this just sounds like complaints from someone who doesn't know the ecosystem and doesn't want to learn it. Someone who thinks your choice of IDE matters for a project, when in fact it doesn't.
> Keeping massive amounts of notes because I'm sure in two weeks I'm going to forget which arcane command I need to keep my Java build environment working.
gradle build
mvn package
> Having to work out which Java runtime environment I need
Do you not have to figure out which version of .net core, .net framework, .net whatever for each project?
> Having to register on the Oracle website to download their runtime,
brew install openjdk@<YOUR_VERSION>
> I can get a new engineer setup to write and deploy .Net in minutes
I use eclipse. Never had problems with it. As for building, I figured out how to use maven to download dependencies to a separate folder and then I use eclipse features to add jars to the project. (Eclipse has maven plugin, but I couldn't get it to work. Something or else made trouble, so I gave up.) Quite pleasant setup.
> Realising that there's no standard equivalent of tasks and async
> An often-asked question is how to synchronously wait on an async method. The usual answer is "don't do it" like it solves anything. But async methods return a Task and the official examples for tasks tell you explicitly to use Wait() method to wait on a task.
`.GetAwaiter().GetResult()` is generally considered the best way to do it if you must do sync over async, but in modern code it should almost never be required.
> I tried to convert a project to NRTs and gave up, reverted everything. I haven't seen a NRE in years :p NRTs introduce a lot of edge cases, with a lot of syntactic noise to cover them and still guarantees nothing (unlike a proper Optional type would).
I've been working on updating a number of libraries to support NRTs with success. I find it's a good for developer ergonomics so you know what can return/be null and what cannot without needing it laid out within xml comments or documentation. ASP.NET Core 5+ will also automatically validate request payloads depending on a type being nullable or not. NRTs will be enabled in project templates by default with .NET 6.
> I'd recommend David Fowler's async guidance for a modern [...] .GetAwaiter().GetResult()
Yeah, you should add to that `ConfigureAwait(false)`.
That you need a long webpage about `async` and that the official documentation on Task doesn't apply kind of drives the point home. They've botched the design of async. Yes, it works "well enough" in 95% of cases, but the remaining 5% is a mine-field.
I know it only confirms your point, but Rider highlights the overloaded operators so you spot them right away.
After working with dotnet for pretty long time and coming to Java world (mostly Spring with Kotlin), I was extremely disappointed to find there's no real alternative to LINQ. What's your solution to this common problem: you have a table (HTML table) with 30 different filters, you need to apply all of them if they're set. Some filters require simple field comparisons, and some filters add very complex conditions.
With LINQ and EF, it's very easy to do, and the result is clean and easy to read. I don't think there's any alternative in Java that does not require adding yet another library and re-implementing data access layer, or writing a lot of boilerplate.
Don't get me started on EF/EFCore. Using it in a large project is _the_ technical decision I regret the most.
As for Java, I wrote a mini-ORM in a week. No big deal. And then I can use SQL as it was intended. EFCore dumbs down the database to being a stupid object store.
> (...) What they did with streams kind of signals that they want to deprecate them in the long run. It's a missed innovation opportunity.
Do they? They kept evolving the Stream API after Java 8 well into Java 16 (Stream::multiMap, Stream::toList, etc.), it doesn't really seem to me like this is true.