Parecidas? Tem certeza?
Veja e conclua…
Com Statement
String query = "SELECT col1, col2, col3 FROM tabela WHERE col4 = 'Teste'";
Statement stm = con.createStatement();
ResultSet rs = stm.executeQuery(query);
Notou a presença do parâmetro diretamente na query?
Outro exemplo
String query = "UPDATE table SET nome = 'Joana', sobrenome = 'D'arc' WHERE id = 10";
Statement stm = con.createStatement(query);
stm.execute();
Será que a query acima roda?
Já com PreparedStatement
String query = "SELECT col1, col2, col3 FROM tabela WHERE col4 = ?";
PreparedStatement pstm = con.prepareStatement(query);
pstm.setString(1, 'Teste');
pstm.execute();
ResultSet rs = pstm.getResultSet();
E quando vou fazer um update
String query = "UPDATE table SET nome = ?, sobrenome = ? WHERE id = ?";
PreparedStatement pstm = con.createStatement(query);
pstm.setString(1, "Joana");
pstm.setString(2, "D'arc");
pstm.setInt(3, 10);
pstm.execute();
Percebe?
O Statement trará, além de problemas com nomes que contém apóstrofos (como Joana D`Arc), a fragilidade à SQL Injection.
PreparedStatement não tem problemas com apóstrofos nem com SQL Injection (num nível óbvio, talvez um mais elaborado possa ocorrer, nada é 100%).