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.
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.
I know of LINQ, but what's EF?
It really, really speeds up the work, but there's a lot of to learn about how does it work, its limitations and conventions
It's an ORM (Object-rational Mapper) for querying SQL databases into objects. Somewhat the same space as "Hibernate" in Java. (2)
Some prefer e.g. Dapper (3) as it's much more light-weight. EF is very much a big thing, but some people need and want that.
This is mostly the fault of the TPL documentation being written eons ago. I'd recommend David Fowler's async guidance for a modern take: https://github.com/davidfowl/AspNetCoreDiagnosticScenarios/b...
`.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.
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.
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.
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.
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 needDo 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 minutesHere's what I do, and it takes 3 minutes:
my_package_manager install openjdk_version_i_need
my_package_manager install maven
my_package_manager install vscode
code --install-extension vscjava.vscode-java-pack
code /path/to/the/project
> recommended one is again verbose, ugly, and more complex to write and understand than Tasks and Async in .Net.This is probably your only valid criticism until Loom is launched.
> Realising that there's no standard equivalent of tasks and async
There is: Executor and CompletableFuture.