Primitivas (mal) embrulhadas

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 i

ersion Survey Site: Converts 1 In 7'>Best Conversion Survey Site: Converts 1 In 7

sso 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 ;-)

zp8497586rq
zp8497586rq