Linguagem de Programao LP
WRAPPERs em Java
Prof. Cristvo Cunha
Assunto: Wrappers
Esta apostila visa explicar e exemplificar o que so Wrappers em Java,
ajudando a aprender como funcionam e como utilizar.
Wrappers vem do verbo ingls wrap que significa envolver. Eles so um nome adicional ao
padro de projeto Decorator. Tem como principal funo envolver coisas adicionando
funcionalidades a elas.
O Java conta com diversos Wrappers que adicionam funcionalidades a outras classes ou tipos
primitivos, um exemplo dele o Integer, que o Wrapper do tipo primitivo int. Que tipo de
funcionalidade voc pode executar tendo apenas uma varivel definida como int? Nenhuma, a
no ser atribuir valores, pois int um tipo primitivo e no possu mtodos.
O Java possui oito wrappers para tipos primitivos que adicionam a funcionalidade de tratar tipos
primitivos como classes. Quando voc faz um:
Integer i = Integer.valueOf(2);
Voc est criando uma classe, que "envolve" o nmero 2 (primitivo) e adiciona mtodos como
intValue() nele. Voc ainda ganha a funcionalidade de trabalhar com o nmero 2 como se ele
fosse um objeto. O Java (a partir da verso 5) inteligente o suficiente para criar ou desfazer
wrappers de tipo primitivo automaticamente (Autoboxing), de to til e comum que essa
prtica, veremos mais a diante como funciona o Autoboxing.
Existem dezenas de wrappers: para tratar o fluxo de conexes como orientado a objetos
(ObjectInputStream), fluxos de audio (AudioInputStream), baseados em tipos primitivos
(DataInputStream), ou adicionar buffers (BufferedInputStream) a eles. Todos esses so
exemplos de wrappers para o bsico e sem funcionalidade InputStream. E o interessante, que,
esses wrappers podem ser combinados (pode-se fazer um FileInputStream, associ-lo a um
BufferedInputStream e ler dados primitivos dele aps associar o resultado a um
DataInputStream).
Com o Wrapper Integer envolvendo o tipo primitivo int voc consegue executar mtodos como
o caso do: parseInt(), valueOf() e assim por diante.
Ento se temos Wrappers porque usar os tipos primitivos? Simples, eles so mais rpidos e
consomem menos memria, afinal no tem implementao de mtodos ou qualquer outro
algoritmo complexo que venha a consumir mais tempo da JVM.
Fique atento ao tentar realizar converses de para Wrappers do tipo errado, pois voc ver
excees como NumberFormatException, como por exemplo a tentativa de converter o literal
dois para um tipo Integer. A ateno deve ser dobrada, pois no h erro em tempo de
compilao, ou seja, seu cdigo no mostrar nenhum erro de sintaxe, mas quando esta linha de
cdigo for executada voc ver a exceo apontada acima. Veja o exemplo da Listagem 1.
int i = l.longValue();
System.out.println(i);
/* no compila
* erro tentando colocar um long dentro de um int
* e isso no valido
*/
}
}
Atente, tambm, que tipos primitivos no podem ser utilizados em Collections, s objetos. Sendo
assim, a soluo usar Wrappers. E j que estamos no assunto de Wrappers, no poderamos
deixar de falar da novidade introduzida a partir do Java 5, o Autoboxing.
Voc j deve ter imaginado que como Wrapper um Objeto voc deve sempre passar um tipo
primitivo para criar um Wrapper especifico daquele tipo primitivo, algo como mostrado na
Listagem 2.
timo, e se quisermos criar um Hashmap teramos que fazer algo como mostrado na Listagem 3.
Aps o Java 5, surgiu a funcionalidade do Autoboxing, onde o prprio Java j converte o tipo
primitivo em Wrapper, se este achar que necessrio. Veja a Listagem 4 com Autoboxing
funcionando.
Boxing Conversion
bvio que se voc tentar realizar um Boxing Conversion de um tipo primitivo para um Wrapper
errado, voc ter um erro de compilao.
Referncia: WrapperBoxing.java
Unboxing Conversion
O Unboxing Conversion quando voc deseja fazer o inverso do item anterior, ou seja, deseja
converter um objeto para um tipo primitivo. Veja os exemplos na Listagem 6.
Referncia: WrapperUnboxing.java
Comparando Wrappers
Possivelmente voc j deve ter comparado Strings em Java, e deve saber que utilizar o operador
== no funciona, por isso, que a implementao do mtodo equals() nos Pojos so muito
importantes. Com os Wrappers voc tambm deve utilizar o mtodo equals() para realizar estes
tipos de comparaes, no esquea que Wrappers so objetos e no tipos primitivos.
A diferena entre o equals e o operador ==, que no operador == ele compara a referncia do
objeto, afinal voc est literalmente comparando os objetos e mesmo que estes fossem idnticos
(em todos os atributos) eles ocupam locais diferentes na memria e possuem identificao
diferente na JVM, resumindo no so iguais. Utilizando o equals voc compara o valor deles, igual
como se tivesse comparando dois tipos primitivos.
Referncia: WrapperEquals.Java
Quando falamos que voc no deve utilizar o == para comparar Wrappers, porque no deve
mesmo e continuamos afirmando isso. Ainda afirmamos que quando voc realizar esse tipo de
comparao receber FALSE, visto que ele compara a referncia em memria do objeto. O
problema que se voc fizer o teste da Listagem 8 ver que ele retornar verdadeiro.
Porque ento o exemplo da Listagem 8 retorna TRUE? Por causa do padro de projeto
Flyweigth. Ele tenta reduzir o consumo de memria mudando a referncia dos objetos que so
idnticos, ou seja, os objetos x e y apontam para um mesmo objeto com que tem as
caractersticas ditando que o valor 120, assim quando compararmos com ==, j que estamos
comparando a referncia do objeto e ela a mesma com o Flyweigth, o resultado ser TRUE. Isso
por padro s aplicado nos valores de -128 at 127, mas na dvida use sempre o equals.
Possivelmente, voc j deve ter usado Wrapper em algum momento, mas nunca soube de fato o
que era, na verdade isso acaba sendo to automtico que muitas das vezes voc deve ter usado
o Integer, Float ou Boolean Wrapper pensado que um tipo primitivo, quando na verdade voc
est envolvido pela Orientao a Objetos.
A importncia destes nem precisa ser descrita, j que so utilizados com freqncia e fazem a
maior parte do trabalho quando precisamos. Alm disso, existem mais Wrappers do que apenas
de tipos primitivos, faa uma pesquisa sobre estes e encontrar um mundo de novos conceitos e
aprendizados.
Wrappers no so utilizados apenas com tipos primitivos, pelo seu conceito de envolver coisas,
podemos utiliz-los em objetos, por exemplo: imagine que voc quer adicionar mais
funcionalidades a um JButton padro, ento voc poderia criar um Wrapper chamado
WrapperJButton que conteria o JButton e mais vrios mtodo que voc acha necessrio para sua
aplicao.
Referncia: WrapperFlyweigth.java
Sendo assim, existe uma classe Wrapper para cada tipo primitivo identificado pelo mesmo nome
do tipo que possui e tendo a primeira letra maiscula. Essa regra de declarao aplicada a todos
os tipos, exceto aos que so char classificados como Character e int como Integer.
De acordo com a hierarquia mostrada na Figura 2, cada tipo wrapper numrico em Java so
subclasses da superclasse abstrata Number (Java.lang.Number) que consegue acessar todos os
mtodos values que so: doubleValue(), floatValue(), longValue(), intValue(), shortValue() e
byteValue().
Glossrio
POJOs: Plain Old Java Objects (Os Singelos Clssicos Objetos Java), so objetos Java que
seguem um desenho simplificado em contraposio aos EJBs, por exemplo.