Wrapper

O que é wrapper…? so sei que java oferece 8 classes wrapper mais o que é isto…?

Wrapper são as classes que representão tipos primitivos.
Integer
Long
Float
Bollean
Byte
Void
Double
Short

Wrapper é um nome adicional ao Pattern decorator.

Basicamente, um decorator permite que você adicione funcionalidade a um objeto (ou tipo primitivo) dinamicamente. Você cria uma nova classe, que “envolve” a classe original e adiciona funcionalidade. O verbo envolver em inglês é “wrap”.

O java possui 8 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 número 2 (primitivo) e adiciona métodos como intValue() nele. Você ainda ganha a funcionalidade de trabalhar com o número 2 como se ele fosse um objeto. O java (a partir da versão 5) é inteligente o suficiente para criar ou desfazer wrappers de tipo primitivo automaticamente (Autoboxing), de tão útil e comum que é essa prática.

Mas esses não são os únicos wrappers que o java possui. Ele ainda possui 6 wrappers adicionais para collections, que as tornam sincronizadas ou imutáveis.

Por exemplo, você pode adicionar sincronização a listas. Todo arraylist não é sincronizado. Entretanto, se quisermos sincronizar um array list podemos fazer:
List minhaLista = Collections.synchronizedList(new ArrayList());

Ou podemos ter uma lista sincronizada e imutável:

List umaLista = new ArrayList(); List umaListaSincronizada = Collections.synchronizedList(umaLista); List umaListaSincronizadaEImutavel = Collections.unmodifiableList(umaListaSincronizada);

Cada decorator desses adicionou uma funcionalidade a mais na lista. A primeira era a sincronização, a segunda imutabilidade.

Se você procurar vai achar ainda mais exemplos de wrappers. Dê uma olhada nos OutputStreams e InputStreams, ou nas classes Reader e Writer…

Existem dezenas de wrappers: para tratar o fluxo de conexões como orientado a objetos (ObjectInputStream), fluxos de audio (AudioInputStream), baseados em tipos primitivos (DataInputStream), ou adicionar buffers (BufferedInputStream) a eles… Todos esses são exemplos de wrappers para o básico e sem funcionalidade InputStream. E o interessante, é que, como demonstrado com as listas, esses wrappers podem ser combinados (pode-se fazer um FileInputStream, associa-lo a um BufferedInputStream e ler dados primitivos dele após associar o resultado a um DataInputStream).

Vou dar um exemplo aqui para ficar mais claro.

Como é implementado o Wrapper do synchronized list?

Ele pode ser essa classe:

[code]public class SynchronizedList implements List {
private List aList; //Lista em que adicionaremos funcionalidade

 public SynchronizedList(List otherList) {
      this.aList = otherList;
 }

 public synchronized void add(Object o} {
       aList.add(o);
 }

 public synchronized boolean remove(Object o) {
       return aList.remove(o);
 }

 //E assim por diante

}[/code]
Agora, sempre que quisermos criar uma lista sincronizada, usamos nosso Wrapper de lista:

List umaLista = new SynchronizedList(new ArrayList());

E isso é exatamente o que o método Collections.synchronizedList faz. Usa uma classe como essa e gera para você uma lista sincronizada, baseada na sua lista.

O que é importante aqui é você não confundir o padrão Wrapper (Decorator) com os wrappers de tipos primitivos, que são apenas exemplos do uso desse padrão.

Intendi cara um exemplo tb é

i=Integer.parseInt(JOptionPane.showInputDialog(“Dígite um número”));

sobre synchronized é uma das poucas palavras chave em java que eu não conheço vc me deu uma boa idéia vou estudar synchronized qualquer dúvida eu posto aki no forum

é vc converte primitivo int, double em objetos Float, Double… sao diferentes float de Float, lembrar de um velho requisito em java ele diferencia maiusculo de minusculo… ja começa por ai de float ser diferente de Float… mais quando usar isso… com collections no java 5 é um de suas utilidades… vc quer criar um conjunto de um tipo especifico… então vc define que vai ser apenas Float, sendo que no java 5 ele faz o AutoBoxing e converte Float em float ai vc pode ter primitivos dentro do seu conjuntos que na verdade é um conjunto de que recebe apenas Float.
Quando estudei pela primeria vez nao conseguir saber a essencia de usar a class Wrapper mais …a medida que vc avançar seu estudo vai ver que vai usa-la com frequencia… hehe! em interfaces graficas é bastante utilizada…

[quote=Puppets]Intendi cara um exemplo tb é

i=Integer.parseInt(JOptionPane.showInputDialog(“Dígite um número”));
[/quote]

Nesse caso você não tem um wrapper. Seu método irá retornar um tipo primitivo int, não uma classe que “envolve” outra para adicionar uma funcionalidade.

Veja o caso do BufferedInputStream. Ele tem como parâmetro de construção um InputStream. Logo, ele criará um buffer, para o InputStream que servirá como parâmetro.

O link que eu passei, do wiki, no post acima explica exatamente como funciona o padrão. Por hora, só decore que Wrappers de tipos primitivos são classes que encapsulam um valor e tem o comportamento parecido com o do tipo primitivo em questão. Por exemplo, o tipo primitivo double pode ser “wrapped” numa classe do tipo Double. Nela você encontrará métodos para soma, subtração ou outras coisas que você poderia fazer num double. Além disso, ela poderá ser usada em listas que aceitem Object, já que objetos do tipo Double são objetos comuns e não tipos primitivos.

Pessoal, primeiramente, desculpe por mexer num tópico tão antigo. Fiz isso apenas para não precisar criar um novo tópico sendo que muitas das informações desse já me ajudaram, porém, queria saber de uma opinião.

Por exemplo, precisei retornar um Date como String para uma necessidade do projeto. Supondo que se fosse o caso de criar um wrapper para o tipo Date para, em vez de criar um SimpleDateFormat, informar o pattern e obter a data como String, adicionar um método nesse wrapper para que faça isso por mim, seria uma boa idéia, ou um exagero?

tipo:

MinhaDate d = new MinhaData();
String dataComoString = d.getAsString("dd/MM/yyyy"); // méu método criado

A princípio eu achei exagero, mas pensando em outras situações de manipulação de Data (ou qualquer outro tipo de dado), em vez de criar classes utilitárias com métodos para fazer isso, poderia ser colocado os métodos nesse wrapper.

O que vcs acham? Simples exagero mesmo ou é por ai?

Vlw

Na minha modesta opinião acho um “exagero”, pois não é necessário reinventar a moda, já que é simples converter uma data para string…
Essa é minha opinião

samykzy, concordo com você, pois foi a primeira coisa que pensei.

Pedi uma opinião, pois (no caso do Date) já encontrei em projetos (inclusive já fiz =D) classes utilitárias com métodos para truncar data; alterar ano, mês ou dia; retornar como String e por ai vai. Daí estive mexendo com isso hoje e resolvi investigar uma melhor prática, principalmente em relação aos wrappers.

Agradeço sua opinião, abraços

[quote=lucastody]samykzy, concordo com você, pois foi a primeira coisa que pensei.

Pedi uma opinião, pois (no caso do Date) já encontrei em projetos (inclusive já fiz =D) classes utilitárias com métodos para truncar data; alterar ano, mês ou dia; retornar como String e por ai vai. Daí estive mexendo com isso hoje e resolvi investigar uma melhor prática, principalmente em relação aos wrappers.

Agradeço sua opinião, abraços[/quote]

Espero que eu não tenha deixado você “burrado” :), é uma opinião minha apenas.

Que isso, muito pelo contrário, opinião é sempre bem vinda.

Se fosse por isso, nem teria postado.

:smiley:

Estou iniciando um curso online de Java e entendi cerca de 8% de como isso funciona…espero que isso se esclareça naturalmente com o passar das aulas!!!

Um bom exemplo que me foi dado foi a conversão de binários para decimal, octal ou hexadecimal…Foi a unica coisa que eu entendi hehehe