Anda di halaman 1dari 7

Anlise e Desenvolvimento de Sistemas ADS

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.

Na Figura 1 voc confere uma lista de Wrappers muito comuns no Java.

Faculdade de Tecnologia de Guaratinguet Prof. Joo Mod


www.fatecguaratingueta.edu.br - e-mail: fatecgt@fatecguaratingueta.edu.br
Av. Prof. Joo Rodrigues Alckmin, 1501 Jardim Esperana, Guaratinguet SP / CEP 12517-475
Tel. (12) 3126-3921 - 3125-7785 - 3126-4849
Figura 1. Wrappers de Tipos Primitivos

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.

Listagem 1. Convertendo de forma errada

public class WrapperException {


public static void main(String[] args) {
int z = Integer.parseInt("dois");
System.out.println(z);
/* cdigo compila sem problemas mais uma exceo vai acontecer
* no h nada de errado na sintaxe
* porem a JVM no consegue converter uma string literal

Faculdade de Tecnologia de Guaratinguet Prof. Joo Mod


www.fatecguaratingueta.edu.br - e-mail: fatecgt@fatecguaratingueta.edu.br
Av. Prof. Joo Rodrigues Alckmin, 1501 Jardim Esperana, Guaratinguet SP / CEP 12517-475
Tel. (12) 3126-3921 - 3125-7785 - 3126-4849
* em um numero inteiro
*/
}
}

Sada: Exception in thread "main" java.lang.NumberFormatException: For


input string: "dois"

//Por outro lado, a classe abaixo ir compilar e executar normalmente


public class WrapperPar {
public static void main(String[] args) {
//String - primitivo
double d = Double.parseDouble("10");
System.out.println(d);
}
}

//A classe abaixo tambm apresentar erro


public class WrapperNoValue {
public static void main(String[] args) {
Long l = new Long(8);
System.out.println(l);

int i = l.longValue();
System.out.println(i);
/* no compila
* erro tentando colocar um long dentro de um int
* e isso no valido
*/
}
}

//Esta funcionar normalmente


public class WrapperValueOf {
public static void main(String[] args) {
//String --> OBJETOS
Float f = Float.valueOf("10");
System.out.println(f);
Integer i = new Integer(10);
System.out.println(i);
//Objeto --> Primitivo
int g = i.intValue();
System.out.println(g);
}
}

//Veja um exemplo de teste de referncia


public class WrapperObject {
public static void main(String[] args) {
Integer g = new Integer(10);
Integer h = new Integer(10);
System.out.println( g == h ); //false

Faculdade de Tecnologia de Guaratinguet Prof. Joo Mod


www.fatecguaratingueta.edu.br - e-mail: fatecgt@fatecguaratingueta.edu.br
Av. Prof. Joo Rodrigues Alckmin, 1501 Jardim Esperana, Guaratinguet SP / CEP 12517-475
Tel. (12) 3126-3921 - 3125-7785 - 3126-4849
/* aqui dois objetos diferentes
* porem com mesmo valor
* == testa a referencia e no valores dos objetos
*/
}
}

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.

Autoboxing com Wrappers

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.

Listagem 2. Criando um Wrapper


Integer soma = new Integer(10);

timo, e se quisermos criar um Hashmap teramos que fazer algo como mostrado na Listagem 3.

Listagem 3. Criando uma lista sem Autoboxing


HashMap hashMap = new HashMap();
hashMap.put(new Integer(10), Carlos);
hashMap.put(new Integer(11), Jose);
hashMap.put(new Integer(12), Pedro);

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.

Listagem 4. Criando uma lista com Autoboxing


HashMap hashMap = new HashMap();
hashMap.put(10, Carlos);
hashMap.put(11, Jose);
hashMap.put(12, Pedro);

Boxing Conversion

O Boxing a converso de tipos primitivos em seu respectivo Wrapper correspondente, ou seja,


veja o exemplo na Listagem 5.

Listagem 5. Boxing Conversion


Boolean meuBoolean = true;
//a converso feita de forma automtica para o boolean
Integer meuInteger = 1203;

Faculdade de Tecnologia de Guaratinguet Prof. Joo Mod


www.fatecguaratingueta.edu.br - e-mail: fatecgt@fatecguaratingueta.edu.br
Av. Prof. Joo Rodrigues Alckmin, 1501 Jardim Esperana, Guaratinguet SP / CEP 12517-475
Tel. (12) 3126-3921 - 3125-7785 - 3126-4849
Double meuDouble = 10.20;

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.

Listagem 6. Exemplos de Unboxing Conversion


boolean a = new Boolean(True);
char c = new Character(c);
byte b = new Byte(1);
float f = new Float(1.0f);

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.

Veja na Listagem 7 uma comparao certa e outra errada.

Listagem 7. Comparando Wrappers da forma certa e da forma errada


Integer a = 200;
Integer b = 200;
a.equals(b); // Retorna TRUE
a == b; // Retorna FALSE

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

Faculdade de Tecnologia de Guaratinguet Prof. Joo Mod


www.fatecguaratingueta.edu.br - e-mail: fatecgt@fatecguaratingueta.edu.br
Av. Prof. Joo Rodrigues Alckmin, 1501 Jardim Esperana, Guaratinguet SP / CEP 12517-475
Tel. (12) 3126-3921 - 3125-7785 - 3126-4849
O Problema encontrado

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.

Listagem 8. Comparando Wrappers com o operador ==


Integer x = 120;
Integer y = 120;
X == y; //Retorna TRUE

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

Resumindo e fixando o conhecimento...

Os Wrappers so conhecidos na linguagem Java como classes especiais que possuem


mtodos capazes de fazer converses em variveis primitivas e tambm de encapsular tipos
primitivos para serem trabalhados como objetos, ou seja, feito um embrulho de streams, que so
fluxo de dados atravs de canais.

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.

Faculdade de Tecnologia de Guaratinguet Prof. Joo Mod


www.fatecguaratingueta.edu.br - e-mail: fatecgt@fatecguaratingueta.edu.br
Av. Prof. Joo Rodrigues Alckmin, 1501 Jardim Esperana, Guaratinguet SP / CEP 12517-475
Tel. (12) 3126-3921 - 3125-7785 - 3126-4849
Figura 2. Hierarquia das Classes Wrappers.

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.

Faculdade de Tecnologia de Guaratinguet Prof. Joo Mod


www.fatecguaratingueta.edu.br - e-mail: fatecgt@fatecguaratingueta.edu.br
Av. Prof. Joo Rodrigues Alckmin, 1501 Jardim Esperana, Guaratinguet SP / CEP 12517-475
Tel. (12) 3126-3921 - 3125-7785 - 3126-4849