Java is sufficiently powerful that it enables ordinary programmers to tackle far more complex problems than are possible in many earlier languages.
I'm rather inclined to disagree with this statement. To suggest that any language is "more powerful" than another is to underestimate the stupidity of ordinary programmers.
The older I get the less I underestimate their stupidity
When I started you had to be interested in the subject and relatively intelligent. Nowadays you only need to be interested in making a living, and the mantra is "everybody should be taught how to code".
Such people should be kept away from keyboards, in the same way I should be kept away from javelins and discuses (discusi?).
Java was specifically designed to be the BB gun to other language's anti-tank guns. So why on earth would anyone choose to use Java when they want to get a job done?
Well, it depends on the job, of course. Bad analogy, of course! A better analogy would be Java=car and, for example, C++=track-laying vehicle.
There are no silver bullets, however much salesmen and fanbois claim otherwise. Similarly there are few complete turds. (But if C++ is The Answer, I think The Question ought to be revisited
)
When I first used Java (in 1996/1997), I was stunned at the speed with which many usable libraries became available, and the ease with which multiple libraries
from multiple sources could be simply bolted into the same application - and "just work". That was something that C++ had failed to achieve in the 10 years it had been around - and arguably is till true to some extent.
Java (and C#) strike a very good balance between rigidity (e.g. you can't cast a horse into a tank), expressivity (e.g. covariance and contravariance), and not having to fight with irrelevancies implementation artefacts (e.g. GC, although you still have to watch out for self-inflicted "data cancer" and a few corner cases). Never underestmate the power of "control-space" in advanced invironments!
Having said that, the unwise overuse of reflection (in the guise of dependency injection) is starting to negate those advantages.
It is the combination of expressivity, extendability and removal of implentation artefacts that makes the Java class environments so powerful - in the sense they enable larger projects and systems to be tackled. Just as procedural HLLs enabled larger systems than assemblers and macrocodes.