Java didn't exist when I originally wrote C++ code. When it did come around it was easily 4x improvement for a good amount of development (eg. enterprise software). I think you need like 4x+ to be worth switching, and I don't see that between many languages. I do see it between libraries/frameworks though.

I think a lot of the problem of switching isn't so much the language, but relearning all the undocumented lessons that were learned the hard way the first time around.

In my experience so far most languages I've encountered have been similar enough that language choice mostly comes down to "Does it have the APIs I need" and "Do I like the tooling." There are a handful of exceptions where the capabilities of the language are fundamentally different enough to provide a competitive edge.

- Systems languages with manual memory management, like C or Zig, where real-time/low-latency performance is important.

- Rust and its borrow checker, as an alternative to manual memory management.

- A strongly FP influenced language such as a Lisp or Haskell. Especially Lisp macros. Exceptionally good for working with structured data in cases where purity is more important than performance.

- The BEAM/OTP architecture for distributed systems (Erlang/Elixir).

- Languages with good CUDA/PTX/Vulkan support, for programs that need the GPU.

- Assembly. This was a much bigger deal in the past before compilers got good. Today good mostly for educational purposes.

I had the same experience. I was put in charge of a large ERP rewrite in C++. Being woefully unprepared we dived in and, based on the issues the existing C codes had, the first thing we built was a memory management framework - what I realized much later was basically garbage collection. It worked very well.

When Java came along its garbage collection blew my mind. I agree with the 4x factor.