Pasando Variables a Métodos en Java

Buenas tardes, en esta entrada vamos a ver lo referente al paso de variables dentro de los métodos.


Los métodos pueden ser declarados para coger tipos de dato primitivos y/o referencias a objeto. Necesitamos saber como ( y si ) la llamada a la variable puede ser afectada por el método llamado. La diferencia entre una referencia a un objeto y una variable primitiva, cuando es pasada a un método, es grande e importante.

  • Pasando Variables de Referencia de un Objeto

    Cuando pasamos una variable objeto dentro a un método, debemos tener claro que estamos pasando la referencia al objeto, y no el objeto actual por sí mismo. Recordemos que una variable de referencia acoge bits que representan una manera de obtener el objeto específico en memoria. Mas importante, debemos recordar que no estamos pasando la variable de referencia actual, sino una copia de la variable de referencia. Una copia de la variable significa que obtenemos una copia de los bits en esa variable, por lo que cuando pasamos una variable de referencia, estamos pasando una copia de los bits que representan como obtener un objeto específico. En otras palabras, lo que llama al método y el método llamado tendrán copias idénticas de la referencia, y así ambos se referirán al mismo objeto exacto (no una copia), localizado en el Heap. Para este ejemplo, usaremos la clase Dimension que está localizada en el paquete java.awt:

    		class ReferenceTest{
    		
    			public static void main (String[] args){
    				Dimension d = new Dimension(5, 10);
    				ReferenceTest rt = new ReferenceTest();
    				System.out.println("Antes de modificar d.height = " + d.height);
    				
    				rt.modify(d);
    				
    				System.out.println("Despues de modify() d.height = " + d.height);
    			}
    			
    			void modify(Dimension dim){
    				dim.height = dim.height + 1;
    				System.out.println("dim = " + dim.height);
    			}
    		}
    		

    Cuando ejecutamos esta clase, podemos ver que el método modify() en efecto ha sido capaz de modificar el objeto Dimension original (y único) creado en la línea 4.

    		Antes de modificar d.height = 10
    		dim = 11
    		Despues de modify() d.height = 11
    		

    Veamos que el objeto Dimension en la línea 4 es pasado al método modify(), y cualquier cambio que le ocurra al objeto dentro del método será aplicado al objeto cuya referencia fue pasada. En el código anterior, las variables de referencia d y dim apuntan ambas al mismo objeto.

  • ¿Usa Java la Semántica Pass-By-Value?

    Si java pasa objetos pasando la variable de referencia , ¿Significa esto que java usa el pass-by-reference (paso por referencia) para objetos?. No exactamente, aunque a veces oigamos y leamos que así lo hace. Java actualmente usa pass-by-value para todas las variables que están siendo ejecutadas dentro de una misma VM. El paso por valor significa pasar por valor de la variable. Y esto significa, pasar por la cppia de la variable.

    No hace diferencia si estamos pasando una variable primitiva o una variable de referencia, estamos siempre pasando una copia de bits en la variable. Para una variable primitiva, estamos pasando una copia de bits que representan el valor. Por ejemplo, si pasamos una variable de tipo int con un valor de 3, estamos pasando una copia de los bits que representan un 3. El método llamado que coge su propia copia del valor, para hacer con ella lo que quiera.

    Si por el contrario estamos pasando al variable de referencia a un objeto, estamos pasando una copia de los bits que representan la referencia a un objeto. El método llamado entonces coge su propia copia de la variable de referencia, para hacer con ella lo que quiera. Pero aunque 2 variables de referencia se refieren al mismo objeto exacto, si el método llamado modifica el objeto (invocando métodos setter, por ejemplo), aquello que llame al método verá que el objeto al cual la variable original se refiere tambien ha cambiado.

    Lo importante en el paso por valor o pass-by-value: El método llamado no puede cambiar la variable que ha usado la aplicación para llamar al método, aunque para variables de referencia a objetos, el método llamado puede cambiar el objeto al cual la variable se refiere. ¿Cuál es la diferencia entre cambiar la variable y cambiar el objeto? Para referencia a objetos, esto significa que el método llamado no puede reasignar la variable de referencia original y hace que se refiera a un objeto diferente, o null. Por ejemplo, en el siguiente fragmento de código:

    		void bar() {
    			Foo f = new Foo();
    			doStuff(f);
    		}
    		
    		void doStuff (Foo g) {
    			g.setName("Boo");
    			g = new Foo();
    		}
    		

    En el ejemplo anterior, reasignar la variable g no reasigna la variable f. Al final del método bar(), 2 objetos Foo han sido creados, uno referenciado por la variable local f y otro referenciado por la variable local (argumento) g. Como el método doStuff() tiene una copia de la variable de referencia, tiene una manera de conseguir el objeto original Foo, por ejemplo para llamar el método setName(). Pero, el método doStuff() no tiene manera de conseguir la variable de referencia f. Por lo que doStuff() puede cambiar valores dentro del objeto f al que se refiere tambien, pero doStuff() no puede cambiar el contenido actual (patrón de bits) de f. En otras palabras, doStuff() puede cambiar el estado del objeto al que f se refiere tambien, pero no puede hacer que f se refiera a un objeto diferente.

  • Pasando Variables Primitivas

    Vamos a echar un vistazo a lo qeu ocurre cuando una variable primitiva es pasada a un método:

    		class ReferenceTest{
    			public static void main (String[] args){
    				int a = 1;
    				ReferenceTest rt = new ReferenceTest();
    				System.out.println("Antes de modify() a = " + a);
    				rt.modify(a);
    				System.out.println("Despues de modify() a = " + a);
    			}
    			
    			void modify(int number){
    				number = number + 1;
    				System.out.println("number = " + number);
    			}
    		}
    		

    En este simple programa, la variable a es pasado a un método llamado modify(), el cual incrementa la variable en 1. El resultado de salida es el siguiente:

    		Antes de modify() a = 1
    		number = 2
    		Despues de modify() a = 1
    		

    Vemos que no ha habido cambios después de que fuera pasado al método. Recordemos, era una copia de lo que fué pasado al método. Cuando una variable primitiva es pasada a un método, es pasada por valor, lo que significa que se pasa una copia de los bits en al variable (pass-by-copy-of-the-bits-in-the-variable).


Aquí todo lo referente a un asunto que tenemos que grabar en la mente, el paso de variables a un método y su posterior modificadión no es el mismo caso cuando pasamos variables primitivas que cuando son variables de referencia de un objeto.

Sin más, cualquier aporte o corrección es bienvenida.

Saludos!!!