Pergunta

Eu queria ter certeza sobre alguma coisa em Java: Se eu tenho um personagem ou um inteiro ou um longo e esse tipo de coisas, devo usar iguais ou é == suficiente?

Eu sei que com cordas, não há garantias de que há apenas uma instância de cada corda única, mas não tenho certeza sobre outros tipos de caixas.

Minha intuição é usar iguais, mas eu quero ter certeza que eu não estou perdendo o desempenho.

Foi útil?

Solução

EDIT: As marcas de especificação alguns garantias para conversões de boxe. De seção 5.1.7 :

Se o valor p ser encaixotado é verdade, falsa, um byte, um char no intervalo \ U0000 para \ u007f, ou um int ou curto número entre -128 e 127, em seguida, deixar R1 e R2 ser os resultados de quaisquer dois conversões de boxe de p. É sempre o caso que R1 == r2.

A implementação pode usar um pool maior, você mente.

eu realmente Evite escrever código que depende de que embora. Não porque ele pode falhar, mas porque não é óbvio - poucas pessoas saberão a especificação que bem. (Eu pensava que era dependente de implementação.)

Você deve usar equals ou comparar os valores subjacentes, i.

if (foo.equals(bar))

ou

if (foo.intValue() == bar.intValue())

Note que mesmo que o autoboxing foram garantidos para usar valores fixos, outros chamadores sempre pode criar instâncias separadas de qualquer maneira.

Outras dicas

Se você quiser comparar nada sobre o valor de qualquer objeto, .equals() uso.

Mesmo (e especialmente) se esses objetos são a primitiva tipos de mensagens publicitárias Byte, Caráter, Short, Integer, Long, Float, Double e booleano.

"==" sempre apenas compara a identidade de objeto e você que é muito, muito raramente o que você quer. E de fato não o que quiser com os wrappers primitivos.

Use apenas == em um desses dois cenários:

  1. todos os valores envolvidos na comparação são tipos de primitivas (e números de ponto flutuante de preferência não)
  2. Você realmente quer saber se duas referências se referem ao mesmo objeto (o que inclui a comparação dos enums, porque não o valor está ligada à identidade de objeto)
//Quick test
public class Test {
  public static void main(String[] args) {
    System.out.println("Are they equal? "+ (new Long(5) == new Long(5)));
  }
}

Output:

"São iguais? 0"

Resposta:

Não, eles não são iguais. Você deve usar .equals ou comparar seus valores primitivos.

linguagem Java Spec 5.1.7 :

Se o valor p ser encaixotado é verdade, falsa, um byte, um char no intervalo \ U0000 para \ u007f, ou um int ou curto número entre -128 e 127, em seguida, deixar R1 e R2 ser os resultados de quaisquer dois conversões de boxe de p. É sempre o caso que R1 == r2.

e

Discussão

Idealmente, boxe um dado primitivo valor de p, que sempre se obter um referência idênticos. Na prática, isto pode não ser factível usando existente técnicas de implementação. As regras acima são um compromisso pragmático. o cláusula final acima requer que certos valores comuns sempre ser encaixotado em objetos indistinguíveis. o implementação pode armazenar em cache estes, preguiçosamente ou ansioso.

Para outros valores, esta formulação não permite quaisquer suposições sobre o identidade dos valores em caixa no parte do programador. Isso permitiria (Mas não exige) a partilha de alguns ou todas estas referências.

Isso garante que em mais comum casos, o comportamento será o desejado um, sem impor uma indevida penalidade de desempenho, especialmente em dispositivos pequenos. Menos limitado memória implementações podem, por exemplo, armazenar em cache todos os personagens e calções, como bem como números inteiros e longs no gama de -32K -. + 32K

Assim, em alguns casos == vai funcionar, em muitos outros, ele não vai. Sempre use .equals para ser seguro desde que você não pode beneficiado (em geral) como os casos foram obtidos.

Se a velocidade é um fator (a maioria .equals começar com uma comparação ==, ou pelo menos deveriam) e você pode gurantee como eles foram alocados E eles se encaixam nas faixas acima, então == é seguro.

Alguns VMs pode aumentar esse tamanho, mas é mais seguro para assumir o menor tamanho, como especificado pela especificação langauge do que contar com um comportamento particular VM, a menos que você realmente realmente realmente precisa.

implementações do equals (Object o) método quase sempre começam com

if(this == o) return true;

isso usando equals mesmo se == é verdade não é realmente muito de um acerto de desempenho.

Eu recomendo sempre * usando o método equals em objetos.

* é claro que existem muito poucos momentos em que você não deve tomar este conselho.

A resposta geral é não , você não está garantido que para o mesmo valor numérico, a longo objetos que você se são as mesmas (mesmo se você restringir-se ao uso de Long.valueOf ()).

No entanto, é possível que você deseja obter uma melhoria de desempenho pela primeira tentativa de testar a igualdade de referências (usando ==) e, em seguida, se falhou, tentando equals (). Tudo depende dos custos comparativos do teste adicional == e a chamada de método ... Sua milhagem pode variar, mas vale a pena tentar um teste de loop simples para ver o que é melhor.

É interessante notar que os valores em caixa-auto irá usos agrupados objeto se eles estiverem disponíveis. É por isso que (Integer) 0 == (Integer) 0 mas (Integer) 128! = (Integer) 128 para Java 6u13

Eu gosto de ver o resultado visual:

  public static void main(String[] args)
  {
        Integer a = 126; //no boxed up conversion, new object ref
        Integer b = 126; //no boxed up conversion, re-use memory address
        System.out.println("Are they equal? " + (a == b)); // true
        Integer a1 = 140; //boxed up conversion, new object
        Integer b1 = 140; //boxed up conversion, new object
        System.out.println("Are they equal? " + (a1 == b1)); // false
        System.out.println("Are they equal? " + (new Long(5) == new Long(5))); // false
  }

== compara a referência de objeto ao equals(Object obj) compara a igualdade do objeto. Se alguma vez pode ser mais do que uma instância de um é igual a objeto na existência , então você deve uso equals para comparação de igualdade.

Exemplos:

Integer i1 = new Integer(12345);
Integer i2 = new Integer(12345);

estes são diferentes instâncias de objetos, mas são iguais de acordo com a igualdade de Integer, por isso você deve usar equals(Object obj)

public enum Gender {
    MALE, FEMALE;
}

Neste caso, haverá apenas uma instância de FEMALE na existência de modo == é seguro para uso.

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