Hola akira, para la pregunta que haces
Entonces mi duda es que basicamente si encerramos ese codigo en un bucle y por ejemplo se ejecuta 5 veces, se crearian 5 objetos pero 1 sola variable referenciadora por lo que solo podria acceder al ultimo objeto que se creó
Es como tú dices, sólo podrías acceder al último objeto y los demás quedarían inaccesibles.
Para poder acceder tendrías que ir almacenando cada objeto creado en una colección, lista o array (de modo que cada objeto tendrá un índice). Luego recorriendo los elementos de esa colección, lista o array podrás acceder a cada uno de los objetos creados.
He probado tu código y funciona, aunque quiero señalarte algunas cosas.
En la clase ListaCantantes no se entiende bien para qué tienes un método copiaValores() y otro método valoresReales(). Los nombres de estos métodos no son adecuados porque no son descriptivos de lo que hace el método. El nombre de un método debe servir para saber qué es lo que hace.
En la clase testIterator tienes una salida de bucle planteada con un break:
else if(valorEntrada.equalsIgnoreCase("n")){
break;
}
En general se considera no aconsejable usar un break para forzar la salida de un bucle y que es preferible que la salida del bucle se produzca de forma natural usando la propia condición del bucle.
Puedes ver este ejercicio resuelto y fijarte en cómo hacerlo:
https://www.aprenderaprogramar.com/foros/index.php?topic=2889.0Saludos