Put another way, the performance details we so often care about in projects for which we're using C++ are often non-local to the calling site. In order to know the performance characteristics of "a = foo(b, c)" I need to know a lot of things about the types of a, b, c, and foo, in addition to knowing what "foo" does inside its curly braces. In contrast, while it's hard to reason about the instructions being executed in Java in the same way we do in C or even to a large degree in C++, the types of a, b, c, and foo don't really matter, since passing in b and c is always a pass by reference or a primitive value copy, and foo is pretty much always going to be dispatched the same way (and constructors are preceded by a "new" operator at the call site, so we don't have to worry about that, either). Now, the only thing I care about is what's inside the foo method.
I am of course not disputing that you need to know the language you're using. It's just that even when you know C++, if you can't trust everyone who ever touched the code, you need to check in a bunch of different places to reason about the performance characteristics of this one piece of code.
Also, reasoning about the performance of C is all well and good right up until you realize that your compiler is better at translating C to assembler than you are and also, some jackass wrote a preprocessor macro called "foo" which does 18 different things. At some point, writing high-performance code is not about assuming you can guess what will happen but about seeing what's happening and trying to make something better happen.
Disclaimer: it's been a good 4 years or so since I worked with Java, and on top of that, I've never cared too much about Java performance, so please take this with a grain of salt.