Java 5 – Novos recursos
Jobson Ronan {[email protected]}
Objetivos


Java 5 Tiger adicionou uma série de recursos novos,
como nenhum outro release do Java havia adicionado
O objetivo desta aula é apresentar as novas
características e recursos da linguagem Java

Principalmente em que estes novos recursos podem nos
ajudar a escrever código mais simples, legível menos
susceptíveis a erros.
Objetivos

Esses novos recursos são







Generics
Enhanced For Loop
Autoboxing/Unboxing
Typesafe Enums
Varargs
Static Imports
Annotations (Metadata)
Generics – Tipos Genéricos

Este recurso ao sistema de tipos esperado a muito tempo
permite um tipo ou um metodo operar sobre objetos de
vários tipos provendo type-safety em tempo de
compilação. Isto adiciona type-safety em tempo de
compilação ao Framework de Collections eliminando a
“sujeria” casting. [JSR 14]
Generics – Tipos Genéricos


Quando se obtém um objeto de um Collection, deve-se
aplicar um cast do tipo do objeto guardado na Collection.
Além de inconveniente, isto é inseguro


O compilador não checa se se o cast é do mesmo tipo da
coleção.
O cast pode falhar em tempo de execução.
Generics – Tipos Genéricos

Generics adicionam um meio de avisar ao compilador o
tipo da coleção


Dessa forma ela pode ser checada.
O compilador sabendo o tipo da coleção, pode checar se
a coleção esta sendo usada consistentemente e inserir os
casts corretos
Generics – Tipos Genéricos

Exemplo simples existente no tutorial de Collecions
(antigo)
// Removes 4-letter words from c. Elements must be strings
static void expurgate(Collection c) {
for (Iterator i = c.iterator(); i.hasNext(); )
if (((String) i.next()).length() == 4)
i.remove();
}

Exemplo modificado usando generics
// Removes the 4-letter words from c
static void expurgate(Collection<String> c) {
for (Iterator<String> i = c.iterator(); i.hasNext(); )
if (i.next().length() == 4) i.remove();
}
Generics – Tipos Genéricos

Quando se escreve <Type>, leia isso com “de Type”


A declaração anterior pode ser lida como “Coleção de Strings”.
O código usando generics é limpo e seguro.


Elimina-se um cast inseguro e um numero de parâmetros
extras.
Mais importante, move-se parte da especificação de um
método do seu comentário para sua assinatura
Generics – Tipos Genéricos

Partes de códigos existentes na definição de List e
Iterator do pacote java.util
public interface List<E> {
void add(E x);
Iterator<E> iterator();
}
public interface Iterator<E> {
E next();
boolean hasNext();
}
Bounded Wilcards

Considere as seguintes declarações
public abstract class Shape {
public abstract void draw(Canvas
}
public class Circle extends Shape {
private int x, y, radius;
public void draw(Canvas c) { ...
}
public class Rectangle extends Shape
private int x, y, width, height;
public void draw(Canvas c) { ...
}

c);
}
{
}
Podemos definir o seguinte metodo
public void drawAll(List<Shape> shapes) {
for (Shape s: shapes) {
s.draw(this);
}
}
Bounded Wilcards

Porém o método não poderia ser chamado sobre um
List<Circle>

Porém queremos que o método aceite listas de qualquer
tipo de Shape
public void drawAll(List<? extends Shape> shapes) { ... }
Enhanced for Loop – “for each”


Esta nova construção da linguagem elimina a necesidade do
Iterators (“sujos” e causadores de erros) ao iterar sobre coleções e
arrays. [JSR 201]
Considere o seguinte metodo que recebe uma coleção de
“TimerTask” e as cancela
void cancelAll(Collection<TimerTask> c) {
for (Iterator<TimerTask> i = c.iterator(); i.hasNext(); )
i.next().cancel();
}

A variavel do iterator aparece 3 veses em cada loop

Isto significa 2 chances de fazer “besteira”
Enhanced for Loop – “for each”


A contrução do “for each” elimina a confusão e as
oportunidades de erros.
Observe o exemplo de como usar o “for each”:
void cancelAll(Collection<TimerTask> c) {
for (TimerTask t : c)
t.cancel();
}

Quando se escreve “dois pontos” (:) leia-se como “em” ou
“de”


No loop acima: “para cada TimerTask t em c”.
Se combina de forma limpa com generics
Enhanced for Loop – “for each”

Um erro comum ao usar Iterators
List suits = ...;
List ranks = ...;
List sortedDeck = new ArrayList();
// BROKEN - throws NoSuchElementException!
for (Iterator i = suits.iterator(); i.hasNext(); )
for (Iterator j = ranks.iterator(); j.hasNext(); )
sortedDeck.add(new Card(i.next(), j.next()));


Alguém consegue ver o bug? Muitos desenvolvedores
experientes cometem este erro uma vez ou outra
O problema é que o metodo next é chamado muitas
vezes na coleção de “fora” (suits)
Enhanced for Loop – “for each”

Para consertar o erro é preciso declarar uma variavel no
escopo do loop de “fora”
// Fixed, though a bit ugly
for (Iterator i = suits.iterator(); i.hasNext(); ) {
Suit suit = (Suit) i.next();
for (Iterator j = ranks.iterator(); j.hasNext(); )
sortedDeck.add(new Card(suit, j.next()));
}

O que isso tem a ver com o “for each”?
for (Suit suit : suits)
for (Rank rank : ranks)
sortedDeck.add(new Card(suit, rank));
Enhanced for Loop – “for each”

Ainda pode ser usado com arrays
// Returns the sum of the elements of a
int sum(int[] a) {
int result = 0;
for (int i : a)
result += i;
return result;
}

Pode-se adicionar suporte do “for each” a qualquer
custon collection

Basta implementar a interface java.lang.Iterable<T>
Enhanced for Loop – “for each”

Use “for each” sempre que puder


Melhora a simplicidade e a qualidade do código
Observe que “for each”s são usados apenas em iterações
onde não se deseja remover ou substituir os elementos
da coleção
Autoboxing/Unboxing

Este recurso elimina a “sujeira” causada pela conversão
manual de tipos primitivos (como int) em wrapper classes
(como Integer) [JSR 201]
Autoboxing/Unboxing

Como era feito a conversão de tipos primitivos em objetos
wrapper
int x = 2;
Integer y = new Integer(3);
int z = x + y.intValue();

Com Autoboxing/Unboxing
int x =
Integer
int z =
Integer
2;
y = 3;
x + y;
w = z;
Autoboxing/Unboxing

Exemplo utilizando autoboxing/unboxing mais generics e
“for each”
import java.util.*;
// Prints a frequency table of the words on the command line
public class Frequency {
public static void main(String[] args) {
Map<String, Integer> m = new TreeMap<String, Integer>();
for (String word : args) {
Integer freq = m.get(word);
m.put(word, (freq == null ? 1 : freq + 1));
}
System.out.println(m);
}
}
> java Frequency if it is to be it is up to me to do the watusi
> {be=1, do=1, if=1, is=2, it=2, me=1, the=1, to=3, up=1, watusi=1}
Typesafe Enums – Tipos enumerados


Uma facilidade de tipos enumerados bem orientada a
objetos com métodos e atributos arbitrários.
Possui todos os benefícios do Typesafe Enum pattern
(“Effective Java”, item 21) sem a grande quantidade de
código necessária.
Typesafe Enums – Tipos enumerados

Antiga forma de representar tipos enumerados
public class PlayingCard {
public static final int
public static final int
public static final int
public static final int
...
}

SUIT_CLUBS = 0;
SUIT_DIAMONDS = 1;
SUIT_HEARTS = 2;
SUIT_SPADES = 3;
Problemas




Não é typesafe
Não possui namespace
Brittleness – Problema da recompilação
Valores impressos não são informativos
Typesafe Enums – Tipos enumerados
Typesafe Enum pattern (Effective Java)

// The typesafe enum pattern
public class Suit {
private final String name;
private Suit(String name) { this.name = name; }
public String toString() { return name; }
public
public
public
public
}
static
static
static
static
final
final
final
final
Suit
Suit
Suit
Suit
CLUBS = new Suit("clubs");
DIAMONDS = new Suit("diamonds");
HEARTS = new Suit("hearts");
SPADES = new Suit("spades");
Typesafe Enums – Tipos enumerados

Java 5 enum
public enum Suit { CLUBS, DIAMONDS, HEARTS, SPADES }

E Java 5 enums ainda





Possuem implementação de alta qualidade a todos os métodos
de Object
Podem possuir métodos e atributos quaisquer
Podem implementar qualquer interface
Implementam Serializable e Comparable
Podem ser usados em um case
Typesafe Enums – Tipos enumerados

Um exemplo
maior
public enum
MERCURY
VENUS
EARTH
...
PLUTO
Planet {
(3.303e+23, 2.4397e6),
(4.869e+24, 6.0518e6),
(5.976e+24, 6.37814e6),
(1.27e+22,
1.137e6);
private final double mass;
// in kilograms
private final double radius; // in meters
Planet(double mass, double radius) {
this.mass = mass;
this.radius = radius;
}
private double mass()
{ return mass; }
private double radius() { return radius; }
// universal gravitational constant (m3 kg-1 s-2)
public static final double G = 6.67300E-11;
double surfaceGravity() {
return G * mass / (radius * radius);
}
double surfaceWeight(double otherMass) {
return otherMass * surfaceGravity();
}
}
Varargs – Multiplos argumentos

Esta nova característica da linguagem Java elimina a
necessidade de empacotar listas em um array ao chamar
métodos que recebem múltiplos argumentos.
Varargs – Multiplos argumentos

Em um passado não muito distante, um método que
aceitava um número arbitrário de valores obrigava a
criação uma array com os valores dentro antes de
proceder com a chamada de método
Object[] arguments = {
new Integer(7),
new Date(),
"a disturbance in the Force"
};
String result = MessageFormat.format(
"At {1,time} on {1,date}, there was {2} on
planet "
+ "{0,number,integer}.", arguments);
Varargs – Multiplos argumentos


Ainda é verdade que múltiplos argumentos precisam ser
passados como um array.
Porém, varargs automatizam e escondem o processo.
String result = MessageFormat.format(
"At {1,time} on {1,date}, there was {2} on planet "
+ "{0,number,integer}.",
7, new Date(), "a disturbance in the Force");

Além disso, é totalmente compatível com a API antiga
Varargs – Multiplos argumentos

Exemplo de declaração
public static String format(String pattern,
Object... arguments);



Os três pontos indicam que o ultimo argumento pode ser
passado como um array ou como uma sequencia de
argumentos
Varargs podem ser usados apenas na posição final da
lista de argumentos
Na implementação do método o argumento multiplo é
acessado como um array
Varargs – Multiplos argumentos

Java agora tem printf

Classe PrintStream
public PrintStream printf(String format,
Object... args)
Static Imports


Este mecanismo permite importar não só definições de
classes, como definições de métodos estáticos e
constantes.
Este mecanismo foi criado visando combater ao
“Constant Interface Antipattern”
Static Imports

Para acessar membros estáticos, era necessário
qualificar as referências com as classes de onde elas
vinham
double r = Math.cos(Math.PI * theta);

Agora pode-se fazer
import static java.lang.Math.PI;

Ou até mesmo
import static java.lang.Math.*;
Static Imports

E finalmente
double r = cos(PI * theta);

A adição deste mecanismo a linguagem Java é, foi e
continua sendo bastante questionada


Pode comprometer a legibilidade do código
Use apenas se você ficar tentado a usar o “Constant
Interface Antipattern”
Annotations (Metadata)

Este mecanismo permite “decorar” classes, métodos e
atributos



Permite adicionar metadados direto no código fonte
Em muitas circunstancias pode ajudar a eliminar a
necessidade de escrever código possibilitando uma
ferramenta gerar este baseado nos metadados presentes
no código fonte
Também elimina a necessidade de manter “side-files”.
Arquivos que precisam ser atualizados conforme
mudanças no código-fonte.
Annotations (Metadata)

Como assim?




Annotations podem ser acessadas via Reflexão.
Então, uma ferramenta pode analisar um código facilmente e
fazer o que quiser com ele.
Annotations não alteram a semântica do programa, mas
podem afetar como o programa é tratado por ferramentas
e bibliotecas.
Programadores típicos nunca precisarão definir um tipo
Annotation. Porém não é difícil faze-lo
Annotations (Metadata)

Criando um mini-framework de para testes automatizados
(from JDK5 Documentation):
import java.lang.annotation.*;
/**
* Indicates that the annotated method is a test method.
* This annotation should be used only on parameterless static methods.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Test { }
Annotations (Metadata)

Um programa simples usando as annotation definidas
public class Foo {
@Test public static void m1() { }
public static void m2() { }
@Test public static void m3() {
throw new RuntimeException("Boom");
}
public static void m4() { }
@Test public static void m5() { }
public static void m6() { }
@Test public static void m7() {
throw new RuntimeException("Crash");
}
public static void m8() { }
}
Annotations (Metadata)

A ferramenta de testes
import java.lang.reflect.*;
public class RunTests {
public static void main(String[] args) throws Exception {
int passed = 0, failed = 0;
for (Method m : Class.forName(args[0]).getMethods()) {
if (m.isAnnotationPresent(Test.class)) {
try {
m.invoke(null);
passed++;
} catch (Throwable ex) {
System.out.printf("Test %s failed: %s %n", m,
ex.getCause());
failed++;
}
}
}
System.out.printf("Passed: %d, Failed %d%n", passed, failed);
}
}
Conclusões




Tantos foram os recursos adicionados na nova
especificação que a linguagem passou de Java 2 para
Java 5!
Muitos destes recursos estavam a muito tempo sendo
pedidos pela comunidade.
Temos que agradecer um pouco a MS
Recursos como generics e annotations mostram a
maturidade de linguagem e dos desenvolvedores!
Exercícios

Implemente a classe GenericStack usando uma lista
ligada e generics contendo os métodos





push(element)
pop()
peek()
size()
Implemente uma classe (ou metodo main) que teste sua
GenericStack
Exercícios

Implemente a classe GenericPriorityList


Ordena a lista a cada inserção de um element
Metodos




add()
getFrist()
removeFrist()
Use Bounded Wildcards para que a lista aceite
qualquer tipo de Comparable<T>
class GenericPriorityList<T extends Comparable<T>>

Use LinkedList e ListIterator
Exercícios


Implemente um enum Mes, com métodos para indicar a
quantidade de dias do mês( getTotalDays())
Implemente um método que recebe um múltiplos objetos
do Tipo Mes e retorna o total de dias da soma dos meses.
Exercícios

Adicione suporte a “for each” para suas listas


GenericStack e GenericPriorityList
Experimente os exemplos de annotations
mostrados na aula
Referências



JDK 5 Documentation
Generics Tutorial,
http://java.sun.com/j2se/1.5/pdf/generics-tutorial.pdf
Joshua Bloch, Effetive Java: Programming Language
Guide, 2001
Java 5 – Novos recursos
Jobson Ronan {[email protected]}
Download

Java 5 - Tiger