The Java compiler does almost no optimization. I think it's an idealistic thing: All optimization is supposed to be done by the JVM. Personally I think that sounds stupid.
Also, please note that both Clang and GCC use the same approach, except in their cases the programmer typically does not see the intermediary code (which is LLVM for Clang, and a family of intermediate languages for GCC).
(Also: it's not a stupid approach. Due to the way the JVM loads things, most of the time you don't know that any particular method won't be overridden later by something that does, in fact, have side effects. There are very few optimizations that could actually be done by the Java compiler.)