I don't know if it's true though.
And then there‘s also Micronaut, if you prefer compile-time setup to Spring.
A completely different culture of Java usage can and does exist a lot of places. It is absolutely true that success creates a certain ossification of practice. But SpringBoot is not necessary, any more than Guice or any other framework-y thing.
Subjective experience, but largely agreed.
Vague rant that summarizes my own experience: major version updates kind of suck, even if Spring Boot is still better than regular Spring (I've gone through the XML hell, was not fun, even less so with a separate Tomcat instance that we had to deploy to, instead of an embedded one). In practice their huge effective pom.xml also leads to conflicts when your package needs something else and it feels a bit arcane to override things. There are things that have underlying technical reasons for being the way they are but seem stupid from afar - like how @Transactional doesn't work when called from within the same bean. Personally I also prefer code over convention for configuration and initialization so the whole annotation driven setup feels quite annoying and difficult to debug when things go wrong - but even the code configuration isn't always great and sometimes it feels like they have abstractions for the sake of abstractions. Spring Boot also often brings friends like MapStruct or Lombok or Mockito which add even more dynamic behavior and issues when you update JDK, alongside slow testing with JUnit and unpleasant debugging of jumping through numerous abstraction layers. You don't strictly have to, but people will.
I probably should have written down every complaint with exact details (so those could be picked apart as user error) over the years that I've been unfortunately maintaining and building shitty software with Java, but I will say this - modern Spring Boot isn't wholly horrible, it has a pretty rich ecosystem and you can do a lot of things with it, but the overall vibe I get from it ofen can be summarized with "Eww." I'd end up using it because I have to, or because it's a means to an end ("Hey, we need to build an event-driven system to integrate with a bunch of others, you have two weeks"), not because I want to.
For the sake of comparison, I believe that for plenty of the folks even Dropwizard would be worth a look: https://www.dropwizard.io/en/stable/ it is more or less like some glue around a bunch of idiomatic packages in the Java ecosystem and it's not horribly hard to integrate something that you want yourself (e.g. Dagger 2 for DI, at this point I'll take anything that does as much as possible at compile time https://dagger.dev/dev-guide/).
Or, for a more modern spin, Quarkus isn't too bad either https://quarkus.io/ or maybe Micronaut https://micronaut.io/ or perhaps Helidon https://helidon.io/ with neither of those being strong recommendations - figure out what you like for yourselves. For people that have been luckier than me, that might as well be the very same Spring Boot, just on better projects. JVM is a pretty cool piece of tech though, and so are the JetBrains IDEs with their refactoring features and nice Maven integration.
> It has become a best of breed language
To me it lags significantly behind .net (runtime) and C#/F# (language). I don't see Java catching-up.
E.g. on the GC side Java is ahead of any other platform, especially with the low-latency ZGC garbage collector.
Currently, this is “magic” embedded in eclipse, IntelliJ, and maybe a bit in the vscode plugin. Imagine having a Java LSP running that can provide all this information while typing.
.net has had this for ages. From a language design I think that is wonderful.
There's also the upcoming Metals v2 that's using another compiler frontend optimized for performance, Google Turbine: https://metals-lsp.org
Actionable diagnostics for Java aren't implemented yet though.
Given that the vast majority of non-GC language code does a terrible job of managing memory, it's not difficult at all for the JVM to win out on efficient, reliable systems.
Bright future for it just means it is not planning to become 40th or 400th.
(My prediction - in next ten years java will always be among top 6; new language might come to the very top and some leapfrogging game between c# and java)
Nonetheless, I agree with your take.
There are many platforms where .NET doesn't have an implementation, a phone to call their own (even if ART isn't proper Java, WP is no longer around), embedded systems, including factory and military weapons deployments (PTC, Aicas, microEJ), copiers (Xerox, Ricoh), phones (Cisco),....
C# is definitly better than Java dealing with value types and low level programing, or being embraced by the game development community, however not sure if the featurities of last years is the right path, I am starting to feel I should just reach directly to C++ instead.
I don't understand what "industry purposes" means and in what aspects Java is better than Go in your opinion (I can think of some myself, but I'm interested in your perspective).
1) No immutable types. My work team is a huge user of immutable data stuctures in Java to make sure data passed around to other teams isn't changed. Go doesn't really have a good way to do this.
2) Refactoring can be really annoying (or at least really noisy) because of public/private being defined by capitalization of method/field names.
3) Error handling isn't great. I love Go's errors being just normal values, but the `error` interface is awkward when trying to figure out what kind of errors can be thrown without having in-depth knowledge of the kinds of errors that can be returned. We regularly need to make different decisions depending on the kind of error returned. Knowing which errors can be returned in Go is not defined by the method being called (only in comments).
The typical answer is opaque types with only readonly methods exported. Not elegant, but it’s there. I guess it’s arguably not a “good way” to do it.
Bit of snark from my side, but that's exactly what makes it less good of a fit for "industry purposes".
Go's error handling is possibly the worst out of any "modern" language, it basically copied C's errno which is not something you should have ever done.
E.g. if I do some IO like "make a copy of these files" and get an error/exception, it's only the caller or maybe even that caller's caller that can properly deal with this condition (e.g. to decide that we will skip the erroneous files or retry).
I'm not sure it's even better than Java's, especially for modern ZGC (and you can choose your GC in Java). Definitely less configurable. I would say most of online comments about Java's GC are long outdated.
For example, in web servers a lot of work is request-response, so it's convenient to utilize generational GCs (so that each request data would fit into "young" generation). Similar to arenas, but without code changes. Go's GC is not generational though, so you should care about allocations.
https://codemia.io/blog/path/The-Evolution-of-Garbage-Collec...
How do I verify that they are actually better? Is the overall performance of my program better? Because that's what I care about. I of course do include memory usage in "performance".
At almost every other case: G1 (the default, just don't add any flags).
Do you want to trade off using less memory at the price of some throughput? Decrease heap size, otherwise don't add anything.
That's it, in most cases just use the default.
They are not. Feel free to look up literally any half-decent benchmarks. If Java's on par or better than any other language of note, check the memory usage. It's standard for Java to have 5-20x the memory usage for about the same performance. The memory floor also seems to be in the hundreds of megabytes. Ridiculous.
> For example, in web servers a lot of work is request-response, so it's convenient to utilize generational GCs (so that each request data would fit into "young" generation).
No, that's a job for arenas. Generational GCs are mostly a result of Java's limitations, and not a univerally good approach.
> Go's GC is not generational though, so you should care about allocations.
You should always care about allocations. In fact, the idea that you shouldn't is a big part of Java's poor performance and design.
In Go, what gives is goroutines have to use some of their time slice to assist the GC and pay down their allocations.
In Java, I believe what you used to get was called "concurrent mode failure" which was somewhat notorious, since it would just stop the world to complete the mark phase. I don't know how this has changed. Poking around a little bit it seems like something similar in ZGC is called "allocation failure"?
The GC assist approach adopted by Go was inspired by real-time GC techniques from the literature and in practice it works nicely. It's not perfect of course, but it's worked just fine for lots of programs. From a purely philosophical point of view, I think it results in a more graceful degradation under unexpectedly high allocation pressure than stopping the world, but what happens in practice is much more situational and relies on good heuristics in the implementation.
And of course it's getting value types now, so it'll win there too. As well as vectors.
So unless you claim that there is no software in Go/C# where the GC is the bottleneck, no, the problem absolutely doesn't solve itself.
It's easy for the USER to fix, since there are flags available. In the day of LLMs it's also easy to find out about those flags and what they do. And if it's so important, testing shouldn't be supremely hard, either.
Normally when you run a non-Java binary, it uses very little memory to start, doesn't have a limit, and returns memory to the system when it frees things. Supposedly you can set JVM flags to do all that, but performance probably suffers, otherwise they would've just done that. So in practice users are always setting the flags carefully.
- Java is a high-level, multi-paradigm programming language
- Go is designed as a systems language to supersede C projects at Google
Now Go identifies as a general purpose language that competes with Java? It's a free country, I guess.
It is a language with a fat runtime, running a garbage collector. You just burn it into the binary and call it a day.
But burning a JVM next to a jar file is not hard at all, one could make something like cosmopolitan.
Actually no. Go was designed from the beginning as a systems language as a C replacement.
Go’s type system, for example, is very much a systems-language artifact. The designers chose structural typing because it was lighter weight, but provided enough type safety to get by. It sucks though for enterprise app development where your team (and your tooling) are desperate for nominal typing clarity and determinism.
But where do Go's docs or founders call it a C replacement? gf000 asked where this is mentioned besides marketing, but I don't see it in the marketing either.
https://web.archive.org/web/20091113154831/http://golang.org...
The main page title *Go: a systems programming language*
It still sports all the low-level stuff too, pointer arithmetic and all.
But then just stay truthful, otherwise C# is also a system PL.
Go's runtime is thin: goroutines, a GC specialized for concurrency, networking, and little else. Java, by contrast, assumes a JVM plus massive stdlibs to handle everything from enterprise apps to big-data, making its platform genuinely "fat" and layered. Other Java-tier languages, C# included, follow the same model.
also has modules now.
Go happened to be attractive for web backends too because it had good greenthreading before Java etc did, and better performance than JS, so it makes sense that they changed the marketing.
I want to say culture around Java doesn't have to change, new culture is growing around succinctness (if not simplicity) of Kotlin, and it gets most of the benefits of Java ecosystem.
inline fun <reified T> Any?.cryptic() = (this as? T)?.let { it::class.simpleName?.also(::println) } ?: UnitIn general, I really dislike extension methods, especially when paired with tiny objects with barely any functionality to begin with. Like people build a mental model of what a thing is based on how can it be used - but if you leave that empty and put every behavior at different files in the form of extension methods you make this understanding very hard to build up.
Add to it that it removes polymorphism and often actually hinders readability.. so my point is, having more ways to write code is not necessarily a positive.
There is quarkus, helidon and micronaut for slimmer more modern backend frameworks. jbang for scripting (think uvx, bunx), Tambo UI (https://tamboui.dev/) for terminal UIs, and more.
Along with all the new Java features that help you write much simpler code - eg. virtual threads, structured concurrency, stream gatherers, and performance / resource improvements.
It's not all there yet, but I think the next few years things will come together nicely (however a better build system is sorely needed - one of the things that Go / Rust did right).
I think this is an often overlooked solution to some of the problems we nowadays tend to approach the clown for.
As for build systems, Maven is old and cranky but if something else replaces it, it will probably be quite similar anyway.
Eventually though, I found Elixir and it gave me everything I was looking for from that stack.
Bazel is the most obvious contender and very different from Maven in almost every possible way.
Switching out Maven for a larger maintenance burden might be reasonable in a large organisation that is swimming in competent employees, but most do not.
As for obvious contender, I'd say that would be Gradle, which is harder to get someone started with than Maven and due to the DSL allows you to invent weirder footguns.
unsure re Maven, 4.0.0 has been around the corner for years, but I think there is space for a modern alternative that is JPMS first, supports semantic versioning (i.e. tilde/carat notation) with lockfiles, and doesn't require a bunch of plugins out of the box for common use-cases. Maybe Mill (https://mill-build.org) - i've yet to try it.
XML is nice, if your pom.xml is massive, just suck it in through JAXB and program against it, perhaps render it to a web page. XSLT can also be helpful. We're not supposed to look at XML as plain text.
Currently I’m trying to externalize as much as possible to the service mesh. I want teams to stand up a basic unencrypted HTTP server that accepts the company headers and just works with as minimal of a runtime as possible.
The Java (now Jakarta) EE standard on top is a good base for third party implementations to "speak a common language", e.g. it's not that hard to move between Quarkus/spring/micronaut etc, even if not all support the actual standard.
It’s still very much an annotation festival in the code, making the framework quite lengthy to learn for newcomers (gotta learn Java and the whole quarkus annotation DSL with it).
Go is verbose, but it is much more explicit and only uses standard language things instead of a whole annotation DSL.
Putting an annotation on a method is much easier than registering this method at n places in ordinary code, which could look any number of ways. If you move to a new project, in the first case can just immediately jump into framework-related stuff, while in the second all this logic has to be untangled first. And let's be honest, Spring/Quarkus probably got their abstraction right after n iterations, which is not necessarily true of a random team.
Maybe it's innate to trying to use a a fully fledged server-style framework in a serverless context, but I don't think it's suitable. In fact I think the whole idea ("Hey, let's bludgeon spring-like metaphors into an entirely new setting") was a poor one.
Java itself I've enjoyed more and more over time as the language has evolved into something much more expressive, and without all the enterprise crap. My hope is that one day frameworks like Micronaut will end up discarded too.
what did you dislike? Pervasive DI? Annotations? configuration mess?
I'm not a massive fan of using annotations in concept, because they obfuscate what's taking place. Unlike in (say) Python, where annotations are effectively functions wrapping the function they annotate, in java they're more akin to a customisable preprocessor. Obviously I do use them, liberally, because that's the way things are done, but I'm not a big fan. And using any modern framework relies on these a lot.
Micronaut gripes -
1. It works great until it doesn't, and you have a special case, and then you have to dig into source to figure out what on earth is going on.
2. Keeping up with latest isn't always easy, micronaut 3->4 was a huge effort.
3. For all it's called micronaut, the produced packages are pretty huge.
Serverless-specific gripes -
1. What I'm receiving isn't really an http message over a socket. It's an AWS gateway event with everything already read and packaged up. So there's no reason that (for instance) I shouldn't access the message body in a request filter, because I don't give a crap about the jetty server-loop being non-blocking.
2. Startup time is terrible. And when I managed to get a native compiled version to actually run, it got worse. A lot of this seems to be down to hibernate, but there's a big gap between startup and any logging from the framework at all. We've tried a bunch of stuff to remediate, so far with little success.
In general I think that serverless is such a different paradigm from a long-running server that approaching it from the point of view of "how can we make this the same so developers who've never thought outside of the spring-like box can still be productive?" was wrong from the outset.
I find that Python decorators can do as much magic as an annotation processor - due to the dynamism of Python. Annotation processors, in most cases, produce a new class based on annotations on existing class / interface. The injection of that class is done by the DI container (unless it's a standalone annotation processor like mapstruct).
> And using any modern framework relies on these a lot.
To be fair to language designers, it's hard to avoid code generators. And they're a compelling thing compared to building proxy objects / DI / decorator / dataclass etc.. kind of functionality in language and getting it wrong.
> ... then you have to dig into source to figure out
Agree. It's not a "boring technology" yet.
> For all it's called micronaut, the produced packages are pretty huge.
How huge? And jlink or graal vm? Just curious.
> A lot of this seems to be down to hibernate,
With micronaut atleast, I remember using Micronaut Data JDBC. Anything is better than hibernate.
> In general I think that serverless is such a different paradigm from a long-running server.
Agreed.
I've found it quite satisfying compared to the other "new" ones.
As for the original topic, I just want to echo what others have said, and say that I am happiest in Java when writing it as if it were Golang code. That an the first-class runtime and performance and deep ecosystem make it a great choice in 2026.
Honestly there are only two reasons I wouldn't pick up Java for personal projects, difficult to build single executable (Graal is still very un-ergonomic), ridiculous build systems.
I can kind of live with former, but Gradle is so very extraordinarily terrible that I don't know where to begin. Problem is, it solves some real problems (in extremely bad way) that people keep using it.
I long of a cargo-style revolution in Java world. (No, the newly popped up alternatives haven't really cut it so far)
Not the case today. Of course, crappy code (or questionable patterns) can be found in all languages, and java community had made some innovations in the area early on, but today we have a different picture.
FactoryFactory has gone mostly extinct, the most likely place to see it is “dailywtf.com”.
We now know that we prefer composition over inheritance, we have stream api - language and community evolved, old patterns are not neccessary anymore to solve same/similar problems.
Sample of one - junit (testing lib) source code, from quick glance it seems more procedural than dogmatic OOP: https://github.com/junit-team/junit-framework/blob/main/juni...
When people say "composition over inheritance" in Java discussions, they usually mean the trivial modeling rule: prefer has-a over is-a.
But that’s not what composition is really about.
The deeper idea is interface composition -- building types by composing multiple behavioral contracts behind a single cohesive surface.
Java provides inheritance and interfaces, but it doesn’t provide first-class delegation or traits. So most developers never really practice interface composition. They either subclass, or they wire objects together and expose the wiring.
The slogan survived. The concept mostly didn’t.
The manifold project, for example, experiments with language-level delegation to make interface composition practical with Java.
https://github.com/manifold-systems/manifold/blob/master/man...
How does a type class help with composition? They do help with the expression problem (adding support for an "interface" after definition), and via parametric polymorphism they might give you a bit with regards to composing two traits.. but you do also have generics in Java, even if not as good as type classes.
So anyways, I don't see as big of a change here. But there was a Brian Goetz mail/presentation somewhere where he talked about adding "basically type classes" to Java? But unfortunately I couldn't find it for you now.
The manifold project provides true delegation[1] for Java.
1. https://github.com/manifold-systems/manifold/blob/master/man...
I'm not sure I am missing first class delegation much (not a lot of UI projects in Java these days).
But interfaces with default (and static) method implementations are actually quite usable as traits / mixins. Since Java 8 IIRC.
You can also pass around functions / lambdas (coincidentally also since Java 8) to compose functionality together. A bit harder to follow and/or understand, but another perfectly legitimate and very powerful tool nevertheless.
it really depends on your project, and what framework(s) and libraries you choose to use.
Java still has a tonne of legacy projects using old(er) frameworks that rely on such patterns - spring has some old versions which is like that, and i am certain plenty of java projects are retaining those old versions due to lack of desire to upgrade.
If you're starting a greenfield development in java, you surely would not befall into that factoryfactory pattern (unless you're just copy/pasting old projects around...). But i imagine there's way fewer greenfield projects compared to older projects requiring maintenance.
JavaScript people are too afraid to use Java, that is why something like TypeScript exists.
And for personal projects, C# has become a better and more fun "just works" platform.
However, I am afraid of the Java coder who is decorated as senior, has sway due to their position, and who will tell me, that something, that is a simple function, shall not be a simple public static "method", but must be wrapped in yet another object, which I need to instantiate, because OOP, and because obviously I don't know what I am doing, or because it doesn't fit existing "coding practices/style" or "Java style". I am afraid of the Java coder, who for years has not touched anything but Java, because their jobs didn't require anything else, because so many companies want Java. I am afraid of the one who throws around jargon like "dependency injection" all day, without ever using simple terms, or realizing what those things are looking like in another paradigm.
Lord, please save me from ever having to work with such obnoxious and uninformed, learning resistant people. This actually may be a straw man, but even one such character matching one or more of those traits, seated above at the seniority ladder will make a mess, that everyone else has to live with.
I wasnt attacking anyone.
Developers are used to the lack of type-safety in JS, and assume that having to code in a type-safe language is something hard. Ive seen this attitude multiple times, it is a known topic.
The issue you are describing is what the author on top mentioned, the culture. It is not just Java, the "enterprise style" coding has infected other languages too. It is the result of how new developers were educated in a time when for example code performance or code readability were only abstract considerations. I fought that style myself multiple times in the past. But thankfully it is going away now.
We are more or less in "chained function call hell" now.
You can use any of the other jdk builds from the plethora of other vendors and have zero interaction with Oracle.
I absolutely hate Oracle as a company, but they've really done a good job with Java stewardship. They actually open sourced the entire language / jdk and a lot of the tooling that used to be proprietary.
They still love to play the old Oracle tricks, so I'd rather not use any of their distributions. But the actual work that they do on the ecosystem has been a positive in my opinion.
It can be Yourdon with C and Pascal, Booch with Smalltalk and C++, Patterns with Smalltalk and C++, UML with Ada, C++, Smalltalk and Java, Rational RUP , Java and .NET application servers, Kubernetes with WebAssembly microservices,....
Ever looked into Typescript with effects, pretending to be Haskell?
Oh. That’s why it’s the top comment.
that's an excuse imho. It's a post-facto justifying using js on the serverside because of familiarity.
I know because the exact same reason was given for GWT (google web toolkit), and that failed pretty horribly (despite it being quite good imho).
It took a long time for the web ecosystem to build up the capabilities that removed the need for GWT.
For a while, it was quite a good way to build and heavily optimize certain kinds of web client applications.
TypeScript is a superior programming environment for the browser, for sure. Using it on the server? Why not, if you're not trying to scale (in capacity, or functionality).
Language-agnostic serialization exists for a good reason. It's not always right, but it's almost always the right thing to do.
Why would anyone create a new language now? The existing ones are "good enough", and without a body of examples for LLMs to train on, a new language has little chance getting traction.
I learned IBM /360 assembler when I started in computers a long time ago. I haven't seen a line of assembler in many decades, but I'm sure it's a viable language still if you need it.
Java has won (alongside many other winners of course), now the AI drawbridge is being raised to stop new entrants and my pick is that Java will still be here in 50 years time, it's just no humans will be creating it.
(Nonetheless, I agree with you)
Compiler writing can be an art form and not all art is for mass consumption.
> Java has won (alongside many other winners of course), now the AI drawbridge is being raised to stop new entrants and my pick is that Java will still be here in 50 years time, it's just no humans will be creating it.
This makes no sense to me. If AI possesses intelligence then it should have no problem learning how to use a new language. If it doesn't possess intelligence, we shouldn't be outsourcing all of our programming to it.
Perfection. You have made such an excellent. However, I don't want to detract from that but it's like, in reality, this is a completely obvious point but because of this AI/LLM brain-rot that has taken over the software programmer community, writ large, this is particularly insightful. It's also just a sad and unimaginative state we are in to think that no more programming languages will ever be needed other than what currently exists in March 2026 because of LLMs.
This is really insulting. I think you're wrong, AI agent programming is very good now, and you will have to admit it at some point.
Obviously not. Insulting to programmers who use them, hence I object to the term "brain-rot". Clearly the insinuation is we're just suffering from brain rot.
Training LLMs on the other hand requires a large amount of training data.
The vast majority of programming languages ever created never aspired to win and I don't think that's going to change now.
I'm writing my own programming language right now... which is for an intensely narrow use case, I'm building a testbed for comparing floating-point implementations without messy language semantics getting in the way.
There's lots of reasons to write your own programming language, especially since if you don't care about it actually displacing existing languages.
Same reason you'd ever create a new language — to start anew, breaking free from the shackles of backwards compatibility of the old language, having learned the lessons of the past.
The AI angle makes even less sense — surely we will want to create languages that are tailored for them.
The 50-year head start in training data, runtime, and ecosystem? That may not be much, because LLMs are rapidly accelerating software development. LLMs can also generalize: take what they learned for one language and apply it to a “similar” language (and I think most modern languages are similar enough for broad effective translation: all have records/unions, objects, functions, types, control-flow, exceptions, and more). Some fairly recent languages (e.g. Rust, Swift) already have comparable runtimes and ecosystems to older ones, from human-driven development acceleration and concept generalization.
In a recent study, LLMs solved the most exercises in Elixir (https://autocodebench.github.io Table 4). Anecdotally, I’ve heard others say that LLMs code best in Rust, and (for UI) Swift. More importantly, I don’t see an older language advantage that is widening from LLM use; an older language probably is better for most use cases today, but any written code can be translated or regenerated into a newer one.
A classic one is C++. Microcontrollers like esp32 cost about $10 these days, for a machine more capable than an early PC.
One downside though is that you typically need C++ to program them, and the barrier to entry with C++ is very high, especially for non-programmers.
LLMs remove that barrier so that anyone can create powerful embedded devices - programmed in C++ - without knowing anything about C++.
People might think they may enjoy another language more, but the portion of people who eventually come to regret choosing Java is probably lower than that of any other language.
Source? I'm not saying you're lying but I have never seen any Java project build as fast as Go
Do you have some sources or experiences to share on this topic? I'm very curious. My experience is the complete opposite.
At my previous job there was a Java web application and running in Kubernetes (1 vCPU and 1Gi of memory) was able to deal with at most 80 requests per second, using up almost the full 1 vCPU and ~600-700MiB of memory. That was a bit disappointing, since we were supposed to support at most ~1000rps on this API, 13+ pods is a lot, and we felt "software could do better".
A reactive guru from another team told us we should use a reactive stack, so he came in and rebuilt the app using the reactive stack. Now it was doing about 120rps on one pod (about the same memory usage), which was a good improvement, but still disappointing.
One guy on the team was motivated to rewrite the API in Go as a proof of concept, and we were blown away. With the same 1 vCPU it was now able to handle 400 requests per second, while using ~100-200MiB of memory, and having approximately 20% better response times.
> builds just as fast (at least when not using some popular build tools)
I find this a little bit of a cop-out, because almost everyone is using the popular build tools. And it's quite a chore to build a full application without those popular build tools. With Go, all batteries for building are included.
That team was using Java 17. Java 21 was just released and frameworks had no meaningful support for virtual threads whatsoever.
In my experience, most companies using Java are chronically multiple versions behind (e.g. some of my friends still in the Java world are on 11).
Perhaps you can share some sources which prove that Java's performance blows Go out of the water without breaking a sweat? I have not seen any such articles about that in the past 3 years, besides the cherry-picked cases where the JVM JIT can optimize some small algorithmic part of the program on the fly (which is not relevant in most web applications).
I'm happy to stand corrected.
Edit: I found this one using a quick search myself https://medium.com/@mohnisha/java-vs-golang-performance-test... I'll check it out and see if I can reproduce it myself too. Still too bad about that gargantuan memory usage, but I guess memory in the cloud is cheap.
Spring was ready on day 1, as virtual threads had been an experimental feature since Java 19. Spring Boot added support within a couple months.
> In my experience, most companies using Java are chronically multiple versions behind (e.g. some of my friends still in the Java world are on 11).
And that's on you.
> And that's on you
What most companies do is on them?
Sorry I have to defend my pride here a little bit. When I joined my previous company, the entire company was on Java 8. When I left every app in every team there was up-to-date on the latest LTS release at the time, 17. I assisted many teams in upgrading their Java, Spring, etc, and inspired even more.
I would argue that I'm one of the last people who you could blame for most companies being many Java versions behind...
As for the build tools, unfortunately the scene is not the best on Java - but javac itself is indeed fast.
Well, dandy! Since the performance gap is that big, it should be trivial to get hard data backing that up. Mind linking some representative benchmarks?
Dang, I just can't wait, same resource usage for Go and Java (RAM in particular, if you would), and Java performance that "blows Go out of the water".
> and builds just as fast
Oh? But you're comparing apples to oranges.
Go builds its source into a machine code executable, all optimizations are applied at this step. This then gets directly executed by the CPU.
Java "builds" its source into bytecode. It's a trivial transformation that then needs to actually be compiled and optimized by a virtual machine at runtime before the CPU can run it.
So then, what build time does Java have when doing AOT compilation? Again, hard numbers please, thanks.
> while offering unmatched deep, low-overhead observability.
> People might think they may enjoy another language more, but the portion of people who eventually come to regret choosing Java is probably lower than that of any other language.
Very believable statements, given that you literally work on Java for Oracle :) No need to bother to make a disclaimer about that I guess. Shameless.
You might want to take a look at what actually happens here. The only reason Go can compile this fast is that it does barely any optimizations. And yeah, javac also does a literal transfomation to Java byte code, no difference here with Go. One will just get a second chance of actually getting optimized via a JIT compiler.
And Java AOT is not doing the same as Go, so again, apples to oranges. It does a complete closed universe build of the program, which requires knowing what classes are ever reachable, and then running their initializers at build time, so they can be burnt into a binary in an initialized state.
There used to be a GNU java compiler doing pretty much what Go did, it's not hard to build, it just wouldn't be compatible with "normal Java", so the use cases would be limited.
Primarily working in Vim/Helix works for most languages from Nix to Typescript or Rust and C, but Java just never worked quite right. It also generally felt like it had a worse story around tooling from a DX perspective, something like Golang or even npm feels a lot lighter than the molasses of JDK management and gradle et al.
Are you joking? IntelliJ is without a doubt the best dev tooling environment available.
Idea was useful for Java but felt quite slow and even with vim bindings was a pain to navigate. Learning the shortcuts helped but it never got quite as fast as helix/vim for general editing (especially as my work usually is a polyglot). It might be the best for Java (compared to eclipse or bluej) but that does not mean it fits my workflow/way of work.
PyCharm/GoLand both are "nice" but it did not feel better/more efficient than pylance/pyright)/gopls + vscode/helix. The only I still occasionally use is DataStorm as it is quite a nice SQLite/PostgreSQL client.
edit: fixed typo from gostorm -> goland
Yet if you ask people in the bay area, especially the those who are under 35, they would tell you that "Use Java? Over my deadbody". It's just amazing that people always chase shiny new things.
The language maintainers have added so many great features while maintaining backwards compatibility. And slowly but surely improved the JVM and garbage collection. So after toying around for a bit, I decided to write some personal projects in Java.
After a week, I gave up and returned to Go. The build tooling is still an over engineered mess. Third party library APIs are still horrible. I will never invest even 5 minutes in learning that horrible Spring framework when stuff like Django, Rails, or the Go ecosystem exist.
The community, and thus the online forums and open source libraries, still approach engineering and aesthetics in a way that is completely foreign and off putting to me.
well there's your problem - why are you using spring for a personal project, when there's so many other simpler, lighter weight frameworks around?
Django and Rails have a very similar model to Spring, so frankly this is just "I was lazy to learn a new tool and it must suck" kinda take. Is there a learning curve? Sure. Does it worth it? I would say for typical CRUD stuff, yeah. No matter how trivial it is you will likely end up needing something that is a single annotation away. But you may want to try quarkus over spring.
The industry purpose for Go is that all codebases look more or less the same, so workers can jump into any project they've never seen before and instantly feel like they wrote it themselves. Google talked about that a lot around the time Go was released. It is why they created it instead of just adopting Haskell or something.
Some of that simply comes down to the language not allowing much creativity, but without the culture developers would still find a way to mess with outcomes. You can still write crazy Go code if you want to. The culture is the piece that matters. If Java doesn't have the culture, how does it fit in industry?
It can be as fast a C, supports a multitude of languages, introspection, surveillance etc.
I've also used Eclipse MAT to find tricky dangling references to objects that caused memory leaks. Definitely not as polished, but extremely useful.
Also that you can start it on a running JVM and it that is has minimal ~1% performance overhead.
It's a runtime, and go also has a similar, fairly fat runtime. It's just burnt into the binary instead of being shipped separately. (Hell, even Rust has a runtime, it's just very very lean compared to languages featuring a full GC like go and java)
The Go runtime is mostly just for goroutines and other runtime stuff, like relection etc.
A go hello world binary is around 1mb, while the java one is (with a jre) up and around 50mb.
I assume you're specifically talking about the backend and not suggesting that people write Applets or use GWT or something.
it has become a best of breed language - hell its better than Go for industry purposes.
the drawback with Java will always be the CULTURE - (maybe someone can insert a quote of how in physics progress is only made, when old physicist die - I don't wanna be morbid ) but with Java same that's when the culture will change.
All those people using typescript (could be using Java - but the culture doesn't want them and consider them heretics for not embracing religion of OOP and FactoryFactory)