I think Go makes a better trade-off than Java, but I struggle to come up with decent examples of projects one could write in Go and not in Java. Most of the “systems” problems that Java is unsuitable for, also apply to Go.
No access to raw threads. No ability to allocate/utilize off-heap memory (without CGo and nonsense atleast). Low throughput compared to Java JIT (unsuitable for CPU intensive tasks).
The only thing I can think of in it's favor is lower memory usage by default but this is mostly just a JVM misconception, you can totally tune it for low memory usage (in constrained env) or high memory efficiency - especially if using off-heap structures.
On a stdlib level Java mostly wins but Go has some highlights, it has an absolutely rock solid and well built HTTP and TLS/X.509/ASN1 stack for instance, also more batteries vs Java.
Overall I think if the requirement is "goes fast" I will always choose Java.
I may pick Go if the brief calls for something like a lightweight network proxy that should be I/O bound rather than CPU bound and everything I need is in stdlib and I don't need any fancy collections etc.
First of all, Go and Java exist at roughly the same performance tier. It will be less work to make Java beat Go for some applications and vice versa for other applications. Moreover, typical Go programs use quite a lot less memory than typical Java programs (i.e., there's more than one kind of performance).
Secondly, Go can make syscalls directly, so it absolutely can use raw-threads and off-heap memory. These are virtually never useful for the "systems" domain (as defined above).
Thirdly, I think Go's stdlib is better if only because it isn't riddled with inheritance. It also has a standard testing library that works with the standard tooling.
Lastly, I think you're ignoring other pertinent factors like maintainability (does a new dev have to learn a new framework, style, conventions, etc to start contributing?), learning curve (how long does it take to onboard someone who is unfamiliar with the language? Are there plugins for their text editor or are they going to have to learn an IDE?), tooling (do you need a DSL just to define the dependencies? do you need a DSL just to spit out a static binary? do you need a CI pipeline to publish source code or documentation packages?), runtime (do you need a GC tuning wizard to calibrate your runtime? does it "just work" in all environments?), etc.
Go is definitely not as fast as Java for throughput. It's gotten pretty good for latency sensitive workloads but it's simply left in the dust for straight throughput, especially if you are hammering the GC.
Sure it can make syscalls directly but if you are going to talk about a maintainability nightmare I can't think of anything worse than trying to manipulate threads directly in Go. I had to do this in a previous Go project where thread pinning was important and even that sucked.
That is just taste. Objectively collections and many other aspects of the Java stdlib completely destroy Go, I pointed out the good bits already.
Again, taste. Java has a slightly steeper and longer learning curve but that is a cost you pay once and is amortized over all the code that engineer will contribute over their tenure.
Using an IDE (especially if everyone is using the same one) is actually a productivity improvement, not an impairment but again - taste. Some people just don't like IDEs or don't like that you need to use a specific one to get the most out of a specific tech stack.
Build systems in Java by and large fall into only 3 camps, Maven, Gradle and a very small (but loud/dedicated) Bazel camp. Contrast that to Go which is almost always a huge pile of horrible Makefiles, CMake, Bazel or some other crazy homebrewed bash build system.
You don't escape CI because you used Go, if you think you did then you are probably doing Go wrong.
Java runtime trades simplicity for ability to be tuned, again taste. I personally prefer it.
So no, I don't think I am mistaken. I think you just prefer Go over Java for subjective reasons. Which is completely OK but doesn't invalidate anything I said.
This isn't even true compared to other comparable platforms like .NET, let alone Go which has hands down the most useful and well constructed standard library in existence (yes, even better than Python).
Especially not when things like this exist: https://pkg.go.dev/container
And things like this don't: https://docs.oracle.com/en/java/javase/17/docs/api/java.base...
As I mentioned Go does have a great HTTP and TLS stack but that doesn't do enough to put it on the same level.
Go was designed for simplicity. Of course it's not the fastest or most feature rich. It's strong suit is that I can pop open any Go codebase and understand what's going on fairly quickly. I went from not knowing any Go to working with it effectively in a large codebase in a couple weeks. Not the case with Java. Not the case with most languages.
Also development time of Java may be slightly longer in the early stages but I generally find refactoring of Java projects and shuffling of timelines etc is a ton easier than Go. So I think Java wins out over a longer period of time even if it starts off a bit slower.
It's far from naive. I have written a shitton of Go code (also a shitton of Java if that wasn't already apparent).
Also, the JVM is way more heavy and resource intensive than a typical Go program. Go is great for cli tools, servers, and the usual "microservices" stuff, whatever it means to you.
Actually, for a long time (almost 20 years, I think), the gcc subsystem gcj let you do AOT compilation of Java to ELF binaries. [1] I think they had to be dynamically linked, but only to a few shared objects (unless you pulled in a lot via native dependencies, but that's kind of "on you").
I don't recall any restrictions on how to use generated code, anymore than gcc-generated object code. So, I don't think the FSF/copyleft on the compiler itself nullifies a free beer classification. :-) gcj may not have done a great job of tracking Java language changes. So, there might be a "doesn't count as 'real Java'" semantic issue.
[1] https://manpages.ubuntu.com/manpages/trusty/man1/gcj.1.html
C# has this. A lot of people overlook C# in this area, probably because until recently, it was not cross-platform.
I would fully agree that Java is a systems language.
However, the definition of "systems language" has been a contentious issue for a very long time, and that debate seems unlikely to be resolved in this thread. I don't think the term itself is very useful, so it's probably better if everyone focuses on discussing things that actually matter to the applications they're trying to develop instead of arguing about nebulous classifications.