Posso passar parâmetros por referência em Java?
ref
palavra-chave.
7 answers
Java é confuso porque tudo é passado pelo valor . No entanto, para um parâmetro de tipo de referência (isto é, não um parâmetro de tipo primitivo) é a referência em si que é passada pelo valor, por isso parece ser pass-by-reference (e as pessoas muitas vezes afirmam que é). Este não é o caso, como mostra o seguinte:
Object o = "Hello";
mutate(o)
System.out.println(o);
private void mutate(Object o) { o = "Goodbye"; } //NOT THE SAME o!
Irá imprimir Hello
para a consola. As opções se você quiser que o código acima para imprimir Goodbye
são para use um referência explícita :
AtomicReference<Object> ref = new AtomicReference<Object>("Hello");
mutate(ref);
System.out.println(ref.get()); //Goodbye!
private void mutate(AtomicReference<Object> ref) { ref.set("Goodbye"); }
Não. Porquê ? Java tem apenas um modo de passar argumentos para métodos: por valor.Posso passar os parâmetros por referência em Java?
Nota:
Para os primitivos isto é fácil de entender: você recebe uma cópia do valor.Para todos os outros você recebe uma cópia da referência e isso é chamado também passando por valor.
Está tudo nesta imagem:
Em Java não há nada ao nível da linguagem semelhante a ref . Em Java só se passa pelo valor semântico
Por curiosidade, você pode implementar uma semântica ref-like em Java simplesmente embrulhar seus objetos em uma classe mutável:
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"
"...Há exatamente um parâmetro que passa o modo em Java-pass by value-e que mantém as coisas simples. .."
Java é sempre passar pelo valor.
Quando se passa por um primitivo é uma cópia do valor, quando se passa por um objecto é uma cópia do ponteiro de referência.Outra opção é usar um array, e.g.
void method(SomeClass[] v) { v[0] = ...; }
mas 1) o array deve ser inicializado antes do método invocado, 2) ainda não se pode implementar, por exemplo, método swap desta forma...
Este modo é utilizado em JDK, por exemplo em java.util.concurrent.atomic.AtomicMarkableReference.get(boolean[])
.