Java has never had a good reputation, lol. But seriously, by every possible measure it has superior competitors:
- Compared to dynamically-typed or interpreted languages, Java performs better, but it requires a frankly ludicrous amount of extra typing.
- Compared to AOT compiled languages, it performs poorly except in purely numeric code where it has the advantage of portable
-march=native
. Other code almost never can be optimized due to the mandatory memory overhead. - Compared to any language, Java lacks support for most forms of ownership that people actually intend, and makes them very difficult to implement them yourself. Of the 3 ownership policies it does support, GC is useless (solely a crutch for programmers who are too lazy or too incompetent to specify what they want), Weak is sabotaged by its relation to GC, and Unique is limited to local contexts and does not compose. (I don't consider Phantom and Soft to actually be distinct ownership types, just hooks for GC ownership)
- In its own niche (static types + JIT + GC), C# is strictly superior as a language, due to supporting value types (although not all C# bothers to use them, at least you have the option of performance). The only disadvantage of C# is in its ecosystem: historically there were a lot of Windows-only libraries; also there were people specifically depending on Java's ecosystem.
Writing your new app in Java is still better than using Electron or something though.
I would say that strings are one of the least inefficient things in the JVM. Yes, you pay double cost for ASCII, but the memory is contiguous unlike Object-heavy code where you have to pay double size cost and an indirection. Also, slicing is "free" unlike many other languages (though make sure you copy if the parent is going to die).