Pergunta

Duplicate possíveis:
é Java “passar por referência”?

Eu encontrei um método Java incomum hoje:

private void addShortenedName(ArrayList<String> voiceSetList, String vsName)
{
     if (null == vsName)
       vsName = "";
     else
       vsName = vsName.trim();
     String shortenedVoiceSetName = vsName.substring(0, Math.min(8, vsName.length()));
     //SCR10638 - Prevent export of empty rows.
     if (shortenedVoiceSetName.length() > 0)
     {
       if (!voiceSetList.contains("#" + shortenedVoiceSetName))
         voiceSetList.add("#" + shortenedVoiceSetName);
     }
}

De acordo com tudo que li sobre o comportamento do Java para passar variáveis, objetos complexos ou não, este código deve fazer exatamente nada. Então, hum ... estou faltando alguma coisa aqui? Existe alguma sutileza que se perdeu em mim, ou faz este código pertence a TheDailyWTF?

Foi útil?

Solução

Como disse Rytmis, Java passa referências por valor. O que isto significa é que você pode legitimamente chamar mutação métodos sobre os parâmetros de um método, mas você não pode reenviá-los e esperar que o valor para se propagar.

Exemplo:

private void goodChangeDog(Dog dog) {
    dog.setColor(Color.BLACK); // works as expected!
}
private void badChangeDog(Dog dog) {
    dog = new StBernard(); // compiles, but has no effect outside the method
}

Editar: O que isto significa, neste caso, é que, embora voiceSetList pode mudar como resultado deste método (que poderia ter um novo elemento adicionado a ele), o mudanças para vsName não será visível fora do método. Para evitar confusão, muitas vezes eu marcar meu parâmetros do método final, o que os impede de ser transferido (acidentalmente ou não) dentro do método. Isso manteria o segundo exemplo de compilar em tudo.

Outras dicas

Java passa referências por valor , de modo a obter uma cópia da referência, mas o objeto referenciado é o mesmo. Assim, este método não modificar a lista de entrada.

As próprias referências são passados ??por valor.

De Java como programar, 4ª Edição por Deitel & Deitel: (. Pg 329)

Ao contrário de outras línguas, Java não permite que o programador de escolher se quer passar cada argumento por valor ou por referência. variáveis ??tipo de dados primitivos são sempre passados por valor. Objectos não são passados ??para métodos; em vez disso, referências a objetos são passados ??para métodos. As referências em si são passados ??por valor-uma cópia de uma referência é passado a um método. Quando um método recebe uma referência a um objecto, o método pode manipular o objeto diretamente.

Usado este livro quando aprender Java na faculdade. referência brilhante.

Aqui está um bom artigo explicando isso. http://www.javaworld.com/javaworld /javaqa/2000-05/03-qa-0526-pass.html

Bem, ele pode manipular o ArrayList - que é um objeto ... se você estiver passando um torno referência de objeto (mesmo passados ??por valor), muda a esse objeto será refletida para o chamador. É que a pergunta?

Eu acho que você está confuso porque vsNome é modificado. Mas, neste contexto, é apenas uma variável local, no mesmo nível exato como shortenedVoiceSetName.

Não está claro para mim o que a pergunta exata dentro do código é. Java é passar por valor, mas matrizes são passar por referência à medida que passam nenhum objeto, mas apenas os ponteiros! Arrays consistem de ponteiros, não objetos real. Isso os torna muito rápido, mas também os torna perigosos de manusear. Para resolver isso, você precisa para cloná-los para obter uma cópia, e mesmo assim ela só vai clone a primeira dimensão da matriz.

Para mais detalhes veja a minha resposta aqui: Em Java, o que é uma cópia superficial? (ver também os meus outras respostas)

A propósito, existem algumas vantagens como matrizes são somente ponteiros: você pode (ab) usá-los como objetos sincronizados

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