Então, o que acontece é o seguinte:
Esses são jeitos de obter uma instância do objeto Class, aquele que descreve a classe (é usado em Reflection):
Class clazz = Class.forName("NomeDaClasse");
Class clazz = NomeDaClasse.class;
Class clazz = new NomeDaClasse().getClass();
Acontece que no dia-a-dia ninguém usa Class.forName() para obter o descritor da classe (Isso é feito por frameworks, ou pela IDE). Ele virou praticamente um “comando para carregar drivers JDBC”, e algumas pessoas acabam não se perguntando o porquê.
O motivo dele funcionar é que para poder te retornar o objeto Class, a JVM precisa carregar a classe primeiro (CASO O PROGRAMA NÃO A TENHA UTILIZADO AINDA).
As classes de driver JDBC, ao serem carregadas, se registram no DriverManager (é uma espécie de contrato que os desenvolvedores de drivers precisam seguir). Isso é feito em um bloco static {} , aquele do código que eu coloquei na outra resposta.
Conclusão: usamos o Class.forName() apenas para nos certificar que naquele ponto a classe do driver foi carregada. Qualquer referência que você fizer a esta classe terá o mesmo efeito, pois a JVM deve carregá-la na primeira utilização.
Por exemplo, estas também são maneiras de carregar o driver do MySQL:
Class clazz = com.mysql.jdbc.Driver.class; // Obtendo o objeto Class
Driver driver = new com.mysql.jdbc.Driver(); // Criando uma instancia
String s = com.mysql.jdbc.Driver.DBNAME_PROPERTY_KEY; // Pegando um atributo estatico qualquer, só para fazer referencia à classe.
// E milhares de outros jeitos :-)
Como um exercício, você pode pensar sobre porque o Class.forName() é melhor do que essas maneiras - tem uma dica em uma das respostas deste tópico…
E finalmente, voltando à sua pergunta original sobre o DriverManager.registerDriver(): não faça dessa maneira, pois o método registerDriver() não é feito para nós e sim para os desenvolvedores de Driver, eles é que tem que se registrar no carregamento da classe (veja aqui) Se você chamar manualmente o driver pode ser registrado em duplicidade.