jueves
oct182012
Seguimos con el paso de parámetros... ¿cómo resolverías el siguiente problema?
Tenemos:
-Lista 1 = Lista de Strings con valores.
-Método 1: tiene visibilidad sobre la vista y llama al método 2.
-Método 2: recibe la lista, realiza modificaciones sobre la misma, agregando, eliminando y modificando.
-Método 1: tiene visibilidad sobre la lista modificada y prosigue la ejecución del programa.
Se pide código, por favor.
tagged certificacion in ocjp
Reader Comments (7)
¿Es algo como ésto lo que pides?
public class Lista {
private final List<String> lista;
public Lista() {
lista = new ArrayList<String>(20);
for (int i = 0; i < 10; i++) {
lista.add(String.valueOf(i));
}
}
public void metodo1() {
metodo2(lista);
}
private void metodo2(final List<String> lista) {
lista.add("nuevo desde metodo2");
lista.remove(lista.get(1));
lista.set(5, "55");
}
}
No man, no vale definición de variables en clase. La variable de lista, en el problema, es sólo accesible desde el método principal, que llama al método dos (que modifica la lista).....
Repetimos...
Te hago una pregunta, @choces, sobre tu código....
private void metodo2(final List<String> lista) {
lista.add("nuevo desde metodo2");
lista.remove(lista.get(1));
lista.set(5, "55");
}
¿Se pueden hacer inserciones de elementos sobre una variable de tipo final?
¿Y si yo hiciera lo siguiente, qué pasaría?
private void metodo2(final List<String> lista) {
lista = new ArrayList<String>();
}
¿Y si hiciera lo siguiente?
private void metodo2(List<String> lista) {
lista = new ArrayList<String>();
}
Preguntas de examen son:
¿Qué salida generaría?
¿Fallo de compilación?
¿Fallo de ejecución?
Recuerda, prueba a contestar sin IDE..... que no es tan fácil entonces ;)
Que el parámetro sea final solo indica que si se reasigna su valor dentro del método, dará un error de compilación.
El otro caso que planteas, ya se ha comentado en otro hilo: la reasignación es local, y el parámetro está "muerto". Ese método no hace nada.
Aunque el parámetro sea final, por supuesto que se puede acceder a sus métodos. Es el mismo caso de un campo de clase declarado como final.
public class Lista {
public void metodo1() {
final List<String> lista = new ArrayList<String>(20);
for (int i = 0; i < 10; i++) {
lista.add(String.valueOf(i));
}
metodo2(lista);
}
private void metodo2(final List<String> lista) {
lista.add("nuevo desde metodo2");
lista.remove(lista.get(1));
lista.set(5, "55");
}
}
Los IDE "no razonan" ;) en el mejor de los casos apuntan a errores de compilación.
Simplemente pasando la lista al método 2, el método 1 ya tiene visibilidad sobre la lista modificada. En Java, el paso de parámetros es por referencia (en realidad, siendo muy puntillosos, no es exactamente así, pero ahora no importa), por lo que cualquier cambio que haga el método 2 a la lista que recibe, será visible para el método uno.
Por ejemplo:
public void metodo1() {
List<String> lista = obtenerListaDeAlgunaForma();
metodo2(lista);
// a partir de aqui, la lista tiene las modificaciones que haya hecho metodo2
}
public void metodo2(final List<String> lista) {
lista.add("algo nuevo");
lista.set("otra cosa");
lista.remove(0);
// seguir modificando la lista a gusto
}
Y sí, se puede modificar la lista aunque sea final. Lo que evita la palabra clave final es la reasignación de la variable. Es decir, en el método 2 no puedes hacer:
lista = new ArrayList<String>();
Eso no compilaría. Pero si puedes llamar tranquilamente a sus métodos. Al hacer el parámetro del metodo 2 final, te aseguras de que accidentalmente no reasignes la variable lista dentro del método (bueno, accidentalmente no, sería por ser un poco manazas :-).
¡Arg! Se me han adelantado :-)
¡Hay que disparar más rápido, forastero! :D