Passe por referência em Java

Aryan Tyagi 12 outubro 2023
Passe por referência em Java

Um ponteiro é uma variável na arquitetura da linguagem de programação que monitora implicitamente o endereço de dados específicos. Um equivalente para outra variável é chamado de referência. Quaisquer modificações feitas na variável de referência têm um impacto direto no original.

Java é uma linguagem transmitida por valor. Ele afirma isso em suas especificações, nunca foi uma linguagem pass-por-referência. Em Java, existe muita confusão entre os dois termos devido à natureza ambígua das referências. Tentaremos esclarecer isso neste artigo.

Vamos discutir a passagem por valor. Aqui, o valor de um parâmetro formal é copiado para um local usado para armazená-lo durante a execução do método / função. Esse local normalmente tem um pedaço de memória alocado para esse propósito.

Na passagem por referência, o valor de um parâmetro formal é copiado para um local usado para armazená-lo durante a execução do método / função. Esse local normalmente tem um pedaço de memória alocado para esse propósito.

Java é promovido como uma linguagem robusta e segura, e um dos benefícios do Java é que ele não habilitava ponteiros como C++. Eles até escolheram um termo diferente para a noção, referindo-se oficialmente a eles como referências.

A chave para entender isso é considerar algo como

Object Obj;

É um ponteiro para o Objeto, não um Obj. O termo referência é mal compreendido em Java e é a fonte da maior parte da confusão. Em outras linguagens de programação, o que eles chamam de referências funcionam como ponteiros.

Quando falamos sobre objetos em Java, estamos falando sobre identificadores de objeto chamados referências, que também são fornecidos por valor.

No código acima, você está efetivamente enviando o endereço do Objeto construído para o método.

Java é semelhante a C por ser uma linguagem procedural. Você pode atribuir um ponteiro a um método, enviá-lo para lá, rastreá-lo dentro do método e alterar os dados para os quais ele apontou. Todas as alterações feitas na posição do ponteiro, por outro lado, passarão despercebidas pelo chamador. (Em uma linguagem de passagem por referência, a função do método pode alterar o ponteiro sem que o chamador perceba.)

Considere que os parâmetros de referência devem ser substituídos por variáveis ​​passadas. A variável que passamos é atribuída quando esse alias é atribuído.

Vamos entender isso melhor com duas situações.

Se alterarmos o próprio objeto e apontá-lo para outro lugar ou objeto, as mudanças não serão refletidas. As mudanças não serão refletidas na função main() se tivermos dado a referência a um local diferente.

Veja o código abaixo.

class Object {
  int x;
  Object(int z) {
    x = z;
  }
  Object() {
    x = 0;
  }
}

class Main {
  public static void main(String[] args) {
    // a reference
    Object O = new Object(7);

    // Reference passed and copy created in change()
    change(O);

    // old value
    System.out.println(O.x);
  }
  public static void change(Object O) {
    // reference changed to some other location any changes not reflected
    O = new Object();

    O.x = 8;
  }
}

Produção:

7

Agora, suponha que não atribuímos uma referência a um novo lugar ou objeto. Nesse caso, os resultados são refletidos de volta: Você pode fazer modificações nos membros. Essas mudanças são refletidas se não alterarmos a referência para se referir a outro objeto (ou local de memória).

Por exemplo,

class Object {
  int x;
  Object(int z) {
    x = z;
  }
  Object() {
    x = 0;
  }
}

class Main {
  public static void main(String[] args) {
    // a reference
    Object O = new Object(7);

    // Reference passed and copy created in change()
    change(O);

    // old value
    System.out.println(O.x);
  }
  public static void change(Object O) {
    O.x = 8;
  }
}

Produção:

8