Pergunta

Estou com um problema com a referência de uma variável ao carregar um objeto serializado salvo de um arquivo de dados.Todas as variáveis ​​que fazem referência ao mesmo objeto não parecem ser atualizadas com a mudança.Criei um código cortado abaixo que ilustra o problema.

    Tournament test1 = new Tournament();
    Tournament test2 = test1;

    try {
        FileInputStream fis = new FileInputStream("test.out");
        ObjectInputStream in = new ObjectInputStream(fis);

        test1 = (Tournament) in.readObject();

        in.close();

    }
    catch (IOException ex){
        Logger.getLogger(Frame.class.getName()).log(Level.SEVERE, null, ex);
    }
    catch (ClassNotFoundException ex){
        Logger.getLogger(Frame.class.getName()).log(Level.SEVERE, null, ex);
    }

    System.out.println("test1: " + test1);
    System.out.println("test2: " + test2);

Depois que esse código é executado, test1 e test2 não fazem mais referência ao mesmo objeto.Que eu saiba, eles deveriam fazer isso, pois na declaração de test2 faz referência a test1.Quando test1 é atualizado, test2 deve refletir a alteração e retornar o novo objeto quando chamado no código.Estou faltando algo essencial aqui ou fui mal ensinado sobre como funcionam as referências de variáveis ​​​​em Java?

Foi útil?

Solução

Estou perdendo algo essencial aqui ou fui enganado sobre como as referências variáveis ​​em Java funciona?

Muito provavelmente você entendeu mal o que lhe foi ensinado ou aprendeu algo errado.Todas as variáveis ​​do tipo de referência (ou seja,tipos não primitivos) consulte directly para um objeto.

Tournament test1 = new Tournament();

Cria uma nova instância de Tournament e faz test1 consulte-o.

Tournament test2 = test1;

Copia a referência de test1 para test2, fazendo com que ambos se refiram ao mesmo objeto.

test1 = (Tournament) in.readObject();

Faz test1 referem-se a um objeto diferente que foi desserializado do fluxo, enquanto test2 ainda se refere ao objeto original.

Outras dicas

Quando você desempacota um objeto com serialização e o atribui a uma variável, você substitui a referência antiga (no seu caso, um new Tournament()) com o novo objeto..então test2 estará apontando para o original Tournament enquanto test1 fará referência ao objeto apenas não serializado.

É como fazer:

Tournament t1 = new Tournament();
Tournament t2 = t1;

t1 = new Tournament();

vai t1 == t2?Claro que não..

Você não está "atualizando" test1 em qualquer lugar.

Esta linha está atribuindo um diferente objeto do tipo Tournament que está lendo o fluxo de entrada e atribuindo esse novo objeto a test1:

test1 = (Tournament) in.readObject();

Enquanto isso, test2 ainda está apontando para o objeto original que foi alocado no início do seu bloco de código.

O problema é a noção de que Java passa e atribui por referência.Isso não acontece.Java passa e atribui por valor.Acontece que com tipos de referência, o valor passado é uma referência.

A diferença é esta:Digamos que você tenha algum código de teste

Tournament test1 = new Tournament();
Tournament test2 = test1;

test1 = new Tournament();
System.out.println(test1 == test2 ? "Equal" : "Not Equal");

Se Java passasse por referência, ele imprimiria Equal, porque test2 seria apenas um apelido para test1.No entanto, como o Java passa por valor, ele imprime Not Equal.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top