Java is safer, because it doesn't use pointer arithmetic, does bounds checking, and doesn't (normally) allow one to access arbitrary chunks of memory (see sun.misc.Unsafe !).
However, similar problems could arise, in principle, if one reads and writes bytes from an array, ByteBuffer, etc according to offsets provided by an untrusted client. The problem is much reduced, because one can only attack data within the bounds of that array (or similar container) rather than data in arbitrary adjacent objects.
Even with Unsafe
, one would typically be, uh, Safe, because one tends to use it for allocating and accessing a very specific set of performance-critical objects, rather than the entire application (including encryption keys, passwords, etc).
The fundamental problem is trusting user input, and that can happen in any language, and a whole variety of contexts, e.g. SQL injection.