Risposte:
Java è confuso perché tutto viene passato per valore . Tuttavia per un parametro di tipo di riferimento (cioè non un parametro di tipo primitivo) è il riferimento stesso che viene passato per valore, quindi sembra essere pass-by-reference (e le persone spesso affermano che lo sia). Questo non è il caso, come mostrato dal seguente:
Object o = "Hello";
mutate(o)
System.out.println(o);
private void mutate(Object o) { o = "Goodbye"; } //NOT THE SAME o!
Stampa Hellosulla console. Le opzioni se si desidera stampare il codice sopra Goodbyesono di utilizzare un riferimento esplicito come segue:
AtomicReference<Object> ref = new AtomicReference<Object>("Hello");
mutate(ref);
System.out.println(ref.get()); //Goodbye!
private void mutate(AtomicReference<Object> ref) { ref.set("Goodbye"); }
Posso passare i parametri per riferimento in Java?
No.
Perché ? Java ha solo una modalità per passare argomenti ai metodi: per valore.
Nota:
Per le primitive questo è facile da capire: ottieni una copia del valore.
Per tutti gli altri si ottiene una copia del riferimento e questo si chiama anche passando per valore.
È tutto in questa immagine:

In Java non esiste nulla a livello di linguaggio simile a ref . In Java c'è solo un passaggio per valore semantico
Per motivi di curiosità puoi implementare una semantica ref-like in Java semplicemente avvolgendo i tuoi oggetti in una classe mutabile:
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();
}
}
TestCase:
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(per i non primitivi)? O AtomicSomething(es . AtomicBoolean:) per i primitivi?
intinvece di Integer, boolinvece di Booleane così via? Cioè, le classi wrapper (che vengono automaticamente scartate se ti preoccupi della sintassi) non funzionano?
Da James Gosling in "Il linguaggio di programmazione Java":
"... Esiste esattamente un modo di passare parametri in Java - passa per valore - e questo semplifica le cose ..."
The pronouncement of the language god should be declared the answernon proprio. Nonostante ciò che il creatore di Java pensa o crede, la risposta assoluta verrebbe da una citazione dalle specifiche del linguaggio.
Non penso che tu possa. La tua migliore opzione potrebbe essere quella di incapsulare la cosa che vuoi passare "per ref" in un'altra istanza di classe e passare il riferimento della classe (esterna) (per valore). Se vedi cosa intendo ...
cioè il tuo metodo cambia lo stato interno dell'oggetto che viene passato, che è quindi visibile al chiamante.
Un'altra opzione è quella di utilizzare un array, ad esempio
void method(SomeClass[] v) { v[0] = ...; }
ma 1) l'array deve essere inizializzato prima che il metodo venga invocato, 2) ancora non è possibile implementare ad esempio il metodo di scambio in questo modo ... Questo modo è usato in JDK, ad esempio in java.util.concurrent.atomic.AtomicMarkableReference.get(boolean[]).