Posso passar parâmetros por referência em Java?

Eu gostaria de semântica semelhante à de ... ref palavra-chave.

Author: oxbow_lakes, 2009-07-01

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"); }
 215
Author: oxbow_lakes, 2009-07-01 13:01:12

Posso passar os parâmetros por referência em Java?

Não. Porquê ? Java tem apenas um modo de passar argumentos para métodos: por valor.

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:

enter image description here

 66
Author: PeterMmm, 2011-09-23 09:13:19

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"
 23
Author: dfa, 2009-11-27 11:45:40
De James Gosling em "A Linguagem de programação Java":

"...Há exatamente um parâmetro que passa o modo em Java-pass by value-e que mantém as coisas simples. .."

 18
Author: duffymo, 2009-07-01 22:06:43
Acho que não consegues. Sua melhor opção pode ser encapsular a coisa que você quer passar "por ref" para outra instância de classe, e passar a referência (externa) da classe (por valor). Se é que me entendes... Ou seja, o seu método muda o estado interno do objeto que é passado, que é então visível para o chamador.
 10
Author: Marc Gravell, 2009-07-01 12:06:14

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.
 5
Author: Nick Holt, 2009-07-01 12:23:50

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[]).

 4
Author: Michal Misiak, 2012-06-25 09:52:22