I am not intimately familiar with Java, so this could be a stupid question.

In a C program I can find buffer overflows or may be a ROP based exploit to run custom code. How is it done in the context of Java? Is it even possible? In Java strings or other data types are all bounded and so overwriting memory is not possible. What about ROP kind of attacks? 

Or more generically what are the typical attack vectors for a Java program?