Java had two tech advantages over C#: It officially ran on platforms other than Windows and ran well, and their JVM was far ahead of the MS CLR.
Both of these things went away/are going away.
What really remains is Java's reputation over "Embrace, Extend, Extinguish Microsoft" (tho Oracle has been busy trying to destroy Java's reputation ever since they bought Sun) and the larger eco-system/community/existing code bases and sunk costs.
That's all of no use to me (I don't work on projects like that), but let's not just shove that aside.
I also don't really agree with this:
> look and wait and do a half-assed implementation of a lot of tried-and-true C# language features some years later
Loom looks like a much more interesting approach compared to async/await hell (I've done it enough to know). I like records and upcoming "withers" much more than { get; set; } (which is easy to write but promotes shit code) because of their focus on immutability. (Yes, I am aware of { get; } and recently introduced { get; init; }, it doesn't really help with the thing withers are trying to solve — copying most fields while replacing one or two values, keeping both the old and the new value immutable). LINQ? maybe, I miss expression trees in Java.There weren't other buyers in town, besides IBM, which I probably would have managed it just as Oracle has, given that the trio have been around in Java world since the early days.
Serialization libraries need to be decoupled from the records being serialized. These two things are compiled into different assemblies, and often written by different people.
Still possible to replace with compile time codegen, but the implementation gonna be complicated and fragile.
If a library doesn't have an API for using them with generics, you can paper over that with:
T fn<T>(T throwAway) => Library.Deserialize<T>();Sometimes people lump these in with dynamic objects but those are a very different class of thing indeed.
Now, what would be -really- nice is if we had a way to specify that an anonymous type implements an interface. That could potentially simplify a -lot- of DTO modeling.