Sim, a cada iteração do loop um novo objeto é criado.
Em Java vc não precisa se preocupar em destruir objetos que não são mais necessários já que o Garbage Collector faz esse trabalho por nós.
Contudo, há classes que alocam recursos quando instanciadas e que precisam liberados. Por exemplo, sempre que vc abre um arquivo, é importante fechá-lo.
O Scanner é uma dessas classes, para liberar seus recursos vc deve chamar o método close().
Tem algumas coisas que vc deve prestar atenção:
1. Vc tem um bom motivo para instanciar o Scanner dentro do loop? Porque vc pode instanciá-lo fora do loop e reaproveitar sempre a mesma instancia sem problema algum. Assim:
Scanner scan = new Scanner(System.in);
int j;
while(j == 0) {
try {
j = scan.nextInt();
} catch(NumberFormatException | InputMismatchException erro) {
System.out.printf("erro: %s\nDigite um número válido", erro);
}
}
scan.close();
2. Esse conceito de criar objetos com o mesmo nome não existe no Java. Pelo que vc está falando, acredito que vc está se referindo às variáveis.
Variáveis não são objetos, são regiões da memória que podem conter objetos. E objetos são instancias de uma classe.
Quando vc declara uma variável dentro de um loop, é como se ela fosse recriada a cada iteração, mas isso não é um problema e as vezes é até recomendável que vc faça isso.
Por exemplo, digamos que no exemplo acima a variável j fosse usada apenas dentro do bloco try, não haveria porque declará-la fora deste bloco e poderiamos seguramente fazer assim:
Scanner scan = new Scanner(System.in);
while(j == 0) {
try {
int j = scan.nextInt();
System.out.println(j);
} catch(NumberFormatException | InputMismatchException erro) {
System.out.printf("erro: %s\nDigite um número válido", erro);
}
}
scan.close();
Quando instanciamos um objeto dentro de um loop, um novo objeto é criado a cada iteração. Esta prática, por si só, não é ruim, mas no exemplo que vc deu, criar varios Scanner é completamente desnecessario.
Eis um exemplo de uma situação em que criar objetos dentro do loop faz sentido:
import java.util.ArrayList;
class Pessoa {
public final String nome;
public final int idade;
public Pessoa(final String nome, final int idade) {
this.nome = nome;
this.idade = idade;
}
@Override
public String toString() {
return String.format("{ nome: %s, idade: %d }", this.nome, this.idade);
}
}
class Main {
public static void main(String... args) {
var pessoas = new ArrayList<Pessoa>();
for(int i = 1; i <= 5; i++) {
Pessoa p = new Pessoa("Pessoa " + i, 20 + i);
pessoas.add(p);
}
pessoas.forEach(System.out::println);
}
}