Compilers for statically-typed languages can play many tricks; code performance can be very tricky to estimate.
For example, in Java the Integer class is final, ie cannot be subclassed.
Therefore, all method calls made via a reference of type Integer can be inlined.
In addition, if the compiler can determine that the integer's lifetime does not extend beyond the function in which it is created (ie in which "new" is called), then the data can be allocated on the stack.
And if the compiler can determine that an Integer is never cast to a parent type (Number or Object), then no Object instance needs to be created, ie just 4 bytes for the data are needed, like in c.
So it can be possible for a good java compiler to create identical code for java or c++ in many cases.
As always,
* actual profiling is best, and
* the tradeoff between safety, performance and developer time must be kept in mind.
There are many things about the Java syntax that annoy me, but the fact that java code can never overwrite memory it does not own is a very powerful thing.