Antes de leer este artículo, según su propia experiencia y comprensión, primero puede pensar y elegir el método de paso de parámetros de las funciones Java:
A. ¿Se pasa por valor?
B. ¿Aprobado por referencia?
C. ¿En parte por valor y en parte por referencia?
La respuesta correcta no se anunciará aquí todavía. Le permitiremos encontrar la respuesta usted mismo mediante un ejemplo sencillo:
1. Primero defina un tipo Valor
valor de clase estática pública { valor de cadena privada = "valor"; cadena pública getValue() { valor de retorno } valor de cadena público (valor de cadena) { this.value = valor;
2. Escriba dos funciones newValue y modifiqueValue: newValue apuntará el parámetro de entrada a un nuevo objeto y modifiqueValue llamará al método setValue del parámetro de entrada para modificar el valor del objeto.
public static void newValue(Valor valor) { valor = nuevo Valor(); valor.setValue("nuevo valor" System.out.println("En nuevoValor, HashCode = " + valor.hashCode() + ", valor = " + value.getValue()); } public static void modificarValue(Valor de valor) { value.setValue("nuevo valor"); System.out.println("En modificarValor, HashCode = " + valor.hashCode() + ", valor = " + valor.getValue()); }
3. Código de prueba sencillo
public static void main(String[] args) { Valor valor1 = nuevo Valor(); Antes de modificar, HashCode = " + valor1.hashCode() + ", valor = " + valor1.getValue() ); // Apunta valor1 al nuevo objeto Valor newValue(value1); System.out.println("Después de modificar, HashCode = " + value1.hashCode() + ", valor = " + valor1.getValue() + "/n"); Valor valor2 = nuevo Valor(); " + value2.getValue()); // Utilice el método set del objeto para modificar el valor interno del objeto modificarValue(value2); System.out.println("Después de modificar, HashCode = " + value2.hashCode() + ", valor = " + value2.getValue());
4. Registro de resultados de ejecución:
Antes de modificar, HashCode = 12677476, valor = valor En newValue, HashCode = 33263331, valor = nuevo valor Después de modificar, HashCode = 12677476, valor = valor Antes de modificar, HashCode = 6413875, valor = valor En modificarValue, HashCode = 6413875, valor = nuevo valor Después de modificar, HashCode = 6413875, valor = nuevo valor
5. Análisis de resultados:
El código anterior es un patrón de programación muy común: definir | guardar | obtener un valor u objeto en la periferia, pasar el objeto como parámetro a un método y modificar las propiedades y el comportamiento del objeto en el método. Sin embargo, los métodos de modificación de los dos métodos newValue y modificaValue son diferentes después de llamar al método, ¡el objeto se ve muy diferente desde el exterior! ¿Cómo entender esta diferencia? Primero revisemos los conceptos de pasar por valor y pasar por referencia:
* Pasar por valor significa que cuando pasas un argumento a una función, la función recibe una copia del valor original. Por lo tanto, si la función modifica el parámetro, solo se cambia la copia, mientras que el valor original permanece sin cambios.
* Pasar por referencia significa que cuando se pasa un argumento a una función, la función recibe la dirección de memoria del valor original en lugar de una copia del valor. Por lo tanto, si la función modifica el parámetro, el valor original del parámetro (en el código de llamada fuera del bloque de funciones) también cambia.
Respuesta correcta: A - ¡Las funciones Java pasan parámetros por valor!
Analizar el registro:
* En la primera sección de la salida del registro, el parámetro value1 se cambia para que apunte a un nuevo objeto dentro del método newValue, y se generan el código hash y el valor del nuevo objeto. Sin embargo, después de saltar fuera del dominio del método newValue, no hay cambios. ocurre con value1 en el método principal. Esto cumple con la definición y las características de pasar por valor; si se pasa por referencia, value1 debería cambiar después de llamar al método newValue (valor de valor).
* La segunda salida del registro muestra que valor2 realiza una operación setValue dentro del método modificarValue. El código hash permanece sin cambios pero el valor se modifica después de salir del dominio del método modificarValue, valor2 cambia en el método principal. Las personas que han usado C++ pueden entender fácilmente este fenómeno como: ¡pasar parámetros de función por referencia! ¡Porque esto es muy similar a pasar por referencia en C++! ¡Pero aquí es exactamente donde es más probable caer en malentendidos!
El principio oculto detrás de los diferentes fenómenos de los dos registros es que el lenguaje Java pasa parámetros por valor y objetos por referencia. Los objetos operados en Java son en realidad referencias a los objetos operativos, y los objetos mismos se almacenan en el "montón"; y la "referencia" del objeto se almacena en un registro o "pila".
El pseudocódigo describe la diferencia entre el método newValue y el método modifiqueValue:
newValue{ Value_ref2 = value_ref1; // Pasa la referencia value_ref1 por valor y obtiene una copia de value_ref1 value_obj2 = new Value(); // value_obj2 se crea e inicializa en el "montón" value_ref2 -> value_obj2; valor_obj2 valor_ref2 - >valor_obj2.setValue(“xxx” // valor_obj2); El valor se modifica printValueObj2(); // Lo que se imprime aquí es el valor de obj2} modifiqueValue{ Value_ref2 = value_ref1; // Pase la referencia value_ref1 por valor y obtenga una copia de value_ref1 value_ref2 ->value_obj1.setValue("xxx "); // Se modifica el valor de value_obj1 printValueObj1(); // Lo que se imprime aquí es el valor de obj1}
¡Eso está bastante claro! Cuando value1_ref1 se pasa a la función como parámetro, primero se copia una copia de value1_ref2 para usarla en el dominio de la función. En este momento, ambas referencias apuntan al mismo código value_obj en la función newObject [value = new Value(); ] De hecho, value1_ref1 apunta a un nuevo objeto value_obj2; las operaciones establecidas después de esto son todas operaciones en el nuevo objeto; la función modificarValue opera directamente value_obj1 a través del método establecido, que es diferente de la función newValue.
Pasar parámetros por valor
Al llamar a un método, debe proporcionar parámetros y debe proporcionarlos en el orden especificado en la lista de parámetros.
Por ejemplo, el siguiente método imprime un mensaje n veces seguidas:
public static void nPrintln(String message, int n) { for (int i = 0; i < n; i++) System.out.println(message);}
Ejemplo El siguiente ejemplo demuestra el efecto de pasar por valor.
Este programa crea un método que intercambia dos variables.
public class TestPassByValue { public static void main(String[] args) { int num1 = 1; int num2 = 2; antes del método de intercambio, num1 es " + num1 + " y num2 es " + num2) ; // Llama al método de intercambio swap(num1, num2 System.out.println("Después del método de intercambio, num1 es " +); num1 + " y num2 es " + num2); } /** Método para intercambiar dos variables*/ public static void swap(int n1, int n2) { System.out.println("/tDentro del método de intercambio"); .out.println("/t/tAntes de intercambiar n1 es " + n1 + " n2 es " + n2); // Intercambia los valores de n1 y n2 int temp = n1 = n1; n2; n2 = temp; System.out.println("/t/tDespués de intercambiar n1 es " + n1 + " n2 es " + n2);
Los resultados de compilación y ejecución del ejemplo anterior son los siguientes:
Antes del método de intercambio, num1 es 1 y num2 es 2 Dentro del método de intercambio Antes de intercambiar n1 es 1 n2 es 2 Después de intercambiar n1 es 2 n2 es 1Después del método de intercambio, num1 es 1 y num2 es 2
Llame al método de intercambio pasando dos parámetros. Curiosamente, los valores de los parámetros reales no cambian después de que se llama al método.