Na verdade temos dois problemas nesse código:
1-quando o compilador sabe que um loop será infinito já no momento da compilação e tem algum código após o loop. Por exemplo, quando fazemos um loop dessa forma
int i;
while(true) {
i = 10;
}
System.out.println(i); // BUM !
no tempo de compilação já é possível descobrir que é um loop infinito. Daí o compilador avisa: “Amigo, eu sei que você sabe o que está fazendo, mas tem um código após esse loop que não será alcançado”.
2-quando não é possível saber, no tempo de compilação, se a variável será inicializada. Vamos imaginar que o loop tenha sido feito assim:
int i;
int b = 10;
while(b == 10) {
i = 10;
b = 9;
}
System.out.println(i); // BUM !
no tempo de compilação, o compilador não sabe qual o valor da variável b. Então ele simplesmente avisa: “Não querendo ser chato, mas você tem uma variável que eu não tenho certeza se foi inicializada, pois, antes da execução, eu não sei o valor de b. Você poderia por gentileza atribuir um valor a mesma”.
No segundo método:
public void metodo2() {
int i;
if(10 == 10) {
i = 10;
}
System.out.println(i); // AQUI FUNFA LEGAL !
}
o compilador não reclama porque, no tempo de compilação, ele sabe que 10 == 10 é verdadeiro e que a variável vai ser inicializada.
Moral da história: Faça o compilador feliz!
É sempre bom inicializar a variável local(mesmo que seja com seu valor padrão) na linha onde é criada, para melhorar a legibilidade do seu código e facilitar o trabalho do compilador.