Respuestas:
Java es confuso porque todo se pasa por valor . Sin embargo, para un parámetro de tipo de referencia (es decir, no un parámetro de tipo primitivo), es la referencia misma la que se pasa por valor, por lo tanto, parece ser una referencia de paso (y las personas a menudo afirman que sí lo es). Este no es el caso, como se muestra a continuación:
Object o = "Hello";
mutate(o)
System.out.println(o);
private void mutate(Object o) { o = "Goodbye"; } //NOT THE SAME o!
Se imprimirá Hello
en la consola. Las opciones si desea que se imprima el código anterior Goodbye
son utilizar una referencia explícita de la siguiente manera:
AtomicReference<Object> ref = new AtomicReference<Object>("Hello");
mutate(ref);
System.out.println(ref.get()); //Goodbye!
private void mutate(AtomicReference<Object> ref) { ref.set("Goodbye"); }
¿Puedo pasar parámetros por referencia en Java?
No.
Por qué ? Java solo tiene un modo de pasar argumentos a los métodos: por valor.
Nota:
Para los primitivos esto es fácil de entender: obtienes una copia del valor.
Para todos los demás, obtienes una copia de la referencia y esto se llama también pasar por valor.
Todo está en esta imagen:
En Java no hay nada a nivel de lenguaje similar a la ref . En Java solo hay paso por valor semántico
En aras de la curiosidad, puede implementar una semántica de referencia en Java simplemente envolviendo sus objetos en una clase mutable:
public class Ref<T> {
private T value;
public Ref(T value) {
this.value = value;
}
public T get() {
return value;
}
public void set(T anotherValue) {
value = anotherValue;
}
@Override
public String toString() {
return value.toString();
}
@Override
public boolean equals(Object obj) {
return value.equals(obj);
}
@Override
public int hashCode() {
return value.hashCode();
}
}
caso de prueba:
public void changeRef(Ref<String> ref) {
ref.set("bbb");
}
// ...
Ref<String> ref = new Ref<String>("aaa");
changeRef(ref);
System.out.println(ref); // prints "bbb"
AtomicReference
(para no primitivos)? O AtomicSomething
(por ejemplo AtomicBoolean
:) para primitivas?
int
lugar de Integer
, en bool
lugar de Boolean
y así sucesivamente? Es decir, ¿las clases de envoltura (que se desenvuelven automáticamente si le preocupa la sintaxis) no funcionan?
De James Gosling en "El lenguaje de programación Java":
"... Hay exactamente un modo de paso de parámetros en Java, pasar por valor, y eso simplifica las cosas ..."
The pronouncement of the language god should be declared the answer
No realmente. A pesar de lo que el creador de Java piensa o cree, la respuesta absoluta vendría de una cita de la especificación del lenguaje.
No creo que puedas. Su mejor opción podría ser encapsular lo que desea pasar "por referencia" a otra instancia de clase y pasar la referencia de la clase (externa) (por valor). Si te das cuenta de lo que quiero decir...
es decir, su método cambia el estado interno del objeto que se pasa, que luego es visible para la persona que llama.
Otra opción es usar una matriz, por ejemplo,
void method(SomeClass[] v) { v[0] = ...; }
pero 1) la matriz debe inicializarse antes de invocar el método, 2) aún no se puede implementar, por ejemplo, el método de intercambio de esta manera ... De esta manera se usa en JDK, por ejemplo, en java.util.concurrent.atomic.AtomicMarkableReference.get(boolean[])
.