Com a introdução do autoboxing na versão 1.5 do Java, a utilização de primitivas começou a cair em desuso, ao ponto de até já haver quem se pergunte se se deve continuar a referir este tipo de variável no ensino do Java (http://www.evolutionnext.com/blog/2004/07/03/1088886468000.html).
Sem duvida que o autoboxing trouxe muitas vantagens a quem escreve código, entre elas, permitir a utilização de primitivas como chaves ou valores nas Collections, mas por outro lado também permite fazer coisas menos bonitas como usar Integers como índices nos ciclos for.
Talvez devido ao facto da sua introdução na linguagem ser relativamente recente, os Wrappers correspondentes a cada uma dos tipos primitivos (Integer, Boolean, Double, etc) nem sempre são usados da forma mais correcta, como é caso dos dois exemplos seguintes que tenho encontrado de forma recorrente em código que revejo:
1 - utilizar == para comparar referências de Wrappers
Depois do compilador converter a primitiva para o Wrapper correspondente, esta passa a ser um objecto e como tal, sujeito às mesmas regras, ou seja, a comparação da igualdade deve ser feita invocando o método .equals() numa referencia válida de um dos Wrappers e não usando o operador ==.
Passemos então ao exemplo:
public class Equalities {
public static void main(String[] args) {
Integer i = 150;
Integer j = 150;
System.out.println(i==j); // false
System.out.println(i.equals(j)); //true
}
}
A comparação de valores usando o operador == falha enquanto que a utilização do método .equals() devolve o resultado esperado. É realmente discutível se o operador == deveria ou não ser 'overloaded' para os Wrappers, como já acontece para as String, mas isso fica para outro post
Já agora uma curiosidade: pela forma como a classe Integer está implementada, se usarmos nas variáveis i e j valores entre -128 e 127, ambos os métodos se comportam da forma esperada, ou seja o operador == devolve true!
2 - Não verificar a validade das referências dos Wrappers quando são passadas como parâmetros para métodos que declaram tipos primitivos
(não liguem, eu gosto de complicar
).
mais uma vez, isto explica-se melhor com um exemplo:
public class Wrapped
public static void main(String[] args) {
Integer testValue=null;
new Object(){
public void m1(Integer p){ // <-- o tipo do parâmetro é um wrapper
System.out.println(p);
};
}.m1(testValue); //escreve 'null'
new Object(){
public void m2(int p){ // <-- o tipo do parâmetro é uma primitiva
System.out.println(p);
};
}.m2(testValue); //lança uma NullPointerException!
}
}
Neste caso, enquanto a chamada ao método m1 escreve, como esperado, 'null', a invocação do método m2 trás-nos a desagradável surpresa: uma NullPoiterException.
O que se passa é que antes de invocar o método m2, a JVM executa o correspondente a invocar o método testValue.intValue() na referencia testValue que por coincidência (ou não, neste caso) é null…
Já agora (mais) uma curiosidade: o FindBugs? detecta correctamente o problema no método m2 (que passa incólume pelo compilador) e assinala-o como 'Null pointer dereference'.
Conclusão : embrulhos sim senhor, mas não se metam em embrulhadas ![]()

0 respostas até ao momento ↓
Ainda não existe comentários. Pode ser o primeiro preenchendo o formulário em baixo.
Deixe um comentário