J2SE 5: l’evoluzione di Java · 2004. 12. 22. · 3 Luca Ferrari J2SE 5: l’evoluzione di Java...

94
1 J2SE 5: l’evoluzione di Java Luca Ferrari 1/188 Luca Ferrari, Dipartimento di Ingegneria dell’Informazione Università di Modena e Reggio Emilia [email protected] - http://agentgroup.unimo.it Seminario del corso di Linguaggi per la Programmazione ad Oggetti (prof. Giacomo Cabri) 20 Dicembre 2004 J2SE 5: l’evoluzione di Java J2SE 5: l’evoluzione di Java Luca Ferrari 2/188 Argomenti Storia (da OAK a J2SE 5) Novità sintattiche (boxing, foreach, varargs, static import, enum, output formattato) Novità semantiche (generics, annotazioni, tipo di ritorno variabili) Classi aggiunte o modificate (Swing, StackTraceElement, InetAdress, Management Factory, …) Varie (Pack200, Ergonomics, …) Risorse

Transcript of J2SE 5: l’evoluzione di Java · 2004. 12. 22. · 3 Luca Ferrari J2SE 5: l’evoluzione di Java...

Page 1: J2SE 5: l’evoluzione di Java · 2004. 12. 22. · 3 Luca Ferrari J2SE 5: l’evoluzione di Java 5/188 … a Tiger Nel 2004, dopo 3 anni di lavoro e due versioni beta, il JDK 1.5.0

1

J2SE 5: l’evoluzione di JavaLuca Ferrari 1/188

Luca Ferrari,Dipartimento di Ingegneria dell’Informazione

Università di Modena e Reggio [email protected] - http://agentgroup.unimo.it

Seminario del corso diLinguaggi per la Programmazione ad Oggetti

(prof. Giacomo Cabri)

20 Dicembre 2004

J2SE 5:l’evoluzione di Java

J2SE 5: l’evoluzione di JavaLuca Ferrari 2/188

ArgomentiStoria

(da OAK a J2SE 5)

Novità sintattiche

(boxing, foreach, varargs, static import, enum, output formattato)

Novità semantiche

(generics, annotazioni, tipo di ritorno variabili)

Classi aggiunte o modificate

(Swing, StackTraceElement, InetAdress, Management Factory, …)

Varie

(Pack200, Ergonomics, …)

Risorse

Page 2: J2SE 5: l’evoluzione di Java · 2004. 12. 22. · 3 Luca Ferrari J2SE 5: l’evoluzione di Java 5/188 … a Tiger Nel 2004, dopo 3 anni di lavoro e due versioni beta, il JDK 1.5.0

2

J2SE 5: l’evoluzione di JavaLuca Ferrari 3/188

Storia

J2SE 5: l’evoluzione di JavaLuca Ferrari 4/188

Da Oak…

Java nasce nella prima metà degli anni ’90 nei laboratori della Sun Microsystems.

L’idea di base viene da Jasmes Gosling, che nel Dicembre ’90 guida, assieme a Patrick Naughton e Mike Sheridan un gruppo di programmatori nel progetto green. Ne scaturisce OAK (1992), un linguaggio ad oggetti innovativo:

“Oak is a programming language looselyrelated to C++. It originated

in a project to produce a software development environment for small

distributed embedded systems.”da “Oak Intermediate Bytecodes”, J.Gosling, ACM Sigplan 95

Oak verrà poi ribattezzato Java, e nel 1995 viene rilasciata la prima versione.

Page 3: J2SE 5: l’evoluzione di Java · 2004. 12. 22. · 3 Luca Ferrari J2SE 5: l’evoluzione di Java 5/188 … a Tiger Nel 2004, dopo 3 anni di lavoro e due versioni beta, il JDK 1.5.0

3

J2SE 5: l’evoluzione di JavaLuca Ferrari 5/188

… a TigerNel 2004, dopo 3 anni di lavoro e due versioni beta, il JDK 1.5.0 viene rilasciato.“It took us close to three years to deliver Tiger, so one lesson welearned is that we were a little too ambitious and we should

probably have to put in a little less and shipped it a little sooner.”(Graham Hamilton,

Java Platform Team Fellow)

Il progetto, denominato Tiger, rappresenta l’upgrade con il numero di innovazioni maggiori nella storia di Java.

J2SE 5: l’evoluzione di JavaLuca Ferrari 6/188

Che nome ha?Java 5 non esiste!

La piattaforma Java è ancora alla versione 2, la versione del linguaggio è la 5.Il nome corretto è: J2SE 5 (J2EE 5).

Page 4: J2SE 5: l’evoluzione di Java · 2004. 12. 22. · 3 Luca Ferrari J2SE 5: l’evoluzione di Java 5/188 … a Tiger Nel 2004, dopo 3 anni di lavoro e due versioni beta, il JDK 1.5.0

4

J2SE 5: l’evoluzione di JavaLuca Ferrari 7/188

Architettura di Java 2

J2SE 5: l’evoluzione di JavaLuca Ferrari 8/188

Ma come nasce una nuova versione?

La SUN ha adottato un sistema chiamato Java Community Process (JCP), attivo da circa 5 anni.

Gli utenti sottomettono delle idee (JSR - Java Specification Requirement), che vengono poi eventualmente discusse, formalizzate, accettate ed implementate.

Alcuni esempi:� JSR 014 (generics)� JSR 175 (annotazioni)� JSR 201 (foreach, autoboxing, enumeration,…)� JSR 163 (JVM Profiling API – JVMTI)

Page 5: J2SE 5: l’evoluzione di Java · 2004. 12. 22. · 3 Luca Ferrari J2SE 5: l’evoluzione di Java 5/188 … a Tiger Nel 2004, dopo 3 anni di lavoro e due versioni beta, il JDK 1.5.0

5

J2SE 5: l’evoluzione di JavaLuca Ferrari 9/188

Siamo rimasti indietro!J2SE 6 (Mustang) è disponibile per il

download!

Si tratta in realtà di daily-snapshots, piuttosto instabili e inutili, a meno che non si sia code developers o beta testers(o curiosi).

Si parla già di J2SE 7 (Dolphin)!

J2SE 5: l’evoluzione di JavaLuca Ferrari 10/188

ArgomentiStoria

(da OAK a J2SE 5)

Novità sintattiche

(boxing, foreach, varargs, static import, enum, output formattato)

Novità semantiche

(generics, annotazioni, tipo di ritorno variabili)

Classi aggiunte o modificate

(Swing, StackTraceElement, InetAdress, Management Factory, …)

Varie

(Pack200, Ergonomics, …)

Risorse

Page 6: J2SE 5: l’evoluzione di Java · 2004. 12. 22. · 3 Luca Ferrari J2SE 5: l’evoluzione di Java 5/188 … a Tiger Nel 2004, dopo 3 anni di lavoro e due versioni beta, il JDK 1.5.0

6

J2SE 5: l’evoluzione di JavaLuca Ferrari 11/188

Autoboxing-Outboxing

J2SE 5: l’evoluzione di JavaLuca Ferrari 12/188

Le classi wrapperJava non è un linguaggio completamente ad oggetti.

I tipi primitivi (int, float, double, …) non sono oggetti!

Per supportare la gestione dei tipi primitivi uniformemente a quella degli altri oggetti, fin da Java 1 sono presenti delle classi wrapper.

Page 7: J2SE 5: l’evoluzione di Java · 2004. 12. 22. · 3 Luca Ferrari J2SE 5: l’evoluzione di Java 5/188 … a Tiger Nel 2004, dopo 3 anni di lavoro e due versioni beta, il JDK 1.5.0

7

J2SE 5: l’evoluzione di JavaLuca Ferrari 13/188

Le classi wrapperL’utilizzo delle classi wrapper risulta scomodo il più delle volte:

Vector v = new Vector();

int i = 10;

...

Integer iObject = new Integer(i);

v.add(iObject);

...

iObject = (Integer)v.get(0);

i = iObject.intValue();

J2SE 5: l’evoluzione di JavaLuca Ferrari 14/188

Autoboxing - OutboxingOra è possibile utilizzare direttamente uno scalare in un contesto di oggetto, lasciando che sia il compilatore a gestire il wrapping del tipo primitivo:

Vector v = new Vector(10);

for(int i=0;i<5;i++){v.add(i);v.add(((float)i)*2.5);

}

for(int i=0;i<v.size();i++){System.out.println(i+"="+

v.elementAt(i));}

0=01=0.02=13=2.54=25=5.06=37=7.58=49=10.0

output di esecuzione

Page 8: J2SE 5: l’evoluzione di Java · 2004. 12. 22. · 3 Luca Ferrari J2SE 5: l’evoluzione di Java 5/188 … a Tiger Nel 2004, dopo 3 anni di lavoro e due versioni beta, il JDK 1.5.0

8

J2SE 5: l’evoluzione di JavaLuca Ferrari 15/188

foreach

J2SE 5: l’evoluzione di JavaLuca Ferrari 16/188

foreachE’ ora supportato il ciclo foreach tramite una sintassi particolare di for:

for( variable_type variable_name : list )

Un ciclo foreach consente di scorrere tutti gli elementi di una lista (ad esempio un array) gestendo automaticamente l’incremento di eventuali indici e l’assegnamento della variabile di ciclo all’elemento successivo.

Page 9: J2SE 5: l’evoluzione di Java · 2004. 12. 22. · 3 Luca Ferrari J2SE 5: l’evoluzione di Java 5/188 … a Tiger Nel 2004, dopo 3 anni di lavoro e due versioni beta, il JDK 1.5.0

9

J2SE 5: l’evoluzione di JavaLuca Ferrari 17/188

foreach: esempiopublic class foreach{

public static void main(String argv[]){String array[] = new String[10];for(int i=0;i<array.length;i++){

array[i] =new String("Stringa n."+i);

}

//utilizzo del foreachfor(String s: array){

System.out.println(s);}

}}

Stringa n.0

Stringa n.1

Stringa n.2

Stringa n.3

Stringa n.4

Stringa n.5

Stringa n.6

Stringa n.7

Stringa n.8

Stringa n.9

output di esecuzione

J2SE 5: l’evoluzione di JavaLuca Ferrari 18/188

foreach: lavorare con strutture datiimport java.util.Vector;public class foreach2{

public static void main(String argv[]){Vector v = new Vector(10);

for(int i=0;i<10;i++){v.add("String n."+i);

}

// uso il foreach// ATTENZIONE: uso di object!for(Object s: v){

System.out.println(s);}

}}

ATTENZIONE: si deve usare un Object perché un Vector memorizza (e restituisce) Object.

foreach non può effettuare i cast automaticamente! Il problema può essere risolto con generics.

Page 10: J2SE 5: l’evoluzione di Java · 2004. 12. 22. · 3 Luca Ferrari J2SE 5: l’evoluzione di Java 5/188 … a Tiger Nel 2004, dopo 3 anni di lavoro e due versioni beta, il JDK 1.5.0

10

J2SE 5: l’evoluzione di JavaLuca Ferrari 19/188

foreach solo per estrazioniforeach non può essere usato come ciclo di assegnamento, ma solo di estrazione:

public static void main(String argv[]){

String array[] = new String[10];

for(String s: array){

s = "CIAO";

}

for(String s:array){

System.out.println(s);

}

}

null

null

null

null

null

null

null

null

null

null

output di esecuzione

J2SE 5: l’evoluzione di JavaLuca Ferrari 20/188

foreach: considerazioniTutto il lavoro “sporco” viene svolto dal compilatore.

Non si ha accesso all’indice numerico della lista (non si è a conoscenza della posizione dell’elemento corrente).

Riduce il rischio di errori banali, come indici fuori dai limiti o cicli annidati sulla stessa variabile.

Non è stata introdotta una parola chiave foreach(come in Perl, C-shell,…) per rispetto al legacy-code.

Page 11: J2SE 5: l’evoluzione di Java · 2004. 12. 22. · 3 Luca Ferrari J2SE 5: l’evoluzione di Java 5/188 … a Tiger Nel 2004, dopo 3 anni di lavoro e due versioni beta, il JDK 1.5.0

11

J2SE 5: l’evoluzione di JavaLuca Ferrari 21/188

Preparare una classe per foreach

Affinché una collezione di dati sia utilizzabile in un ciclo foreach, occorre che l’interfaccia Iterable sia implementata.

J2SE 5: l’evoluzione di JavaLuca Ferrari 22/188

foreach: una nota di demeritoL’implementazione di foreach non è null-safe (al contrario di Perl):

String array[]=null;

for(String s:array){

System.out.println(s);

} String array[]=null;

for(int i=0;i<array.length;i++){

String s = array[i];

System.out.println(s);

}

NullPointerException

Page 12: J2SE 5: l’evoluzione di Java · 2004. 12. 22. · 3 Luca Ferrari J2SE 5: l’evoluzione di Java 5/188 … a Tiger Nel 2004, dopo 3 anni di lavoro e due versioni beta, il JDK 1.5.0

12

J2SE 5: l’evoluzione di JavaLuca Ferrari 23/188

foreach: una nota di demeritoUna implementazione più sicura sarebbe stata:

String arr []=null;

for(String s:arr){

System.out.println(s);

} String arr []=null;

for(int i=0;arr!=null && i<arr.length;i++){

String s = array[i];

System.out.println(s);

}

J2SE 5: l’evoluzione di JavaLuca Ferrari 24/188

varargs

Page 13: J2SE 5: l’evoluzione di Java · 2004. 12. 22. · 3 Luca Ferrari J2SE 5: l’evoluzione di Java 5/188 … a Tiger Nel 2004, dopo 3 anni di lavoro e due versioni beta, il JDK 1.5.0

13

J2SE 5: l’evoluzione di JavaLuca Ferrari 25/188

varargsE’ ora possibile definire metodi che accettino un numero variabile di argomenti.

Gli argomenti devono avere tutti lo stesso tipo, al limite Object (che equivale a “tutti i tipi possibili”).

La sintassi prevede l’uso dell’operatore … fra il tipo e il nome associato all’argomento.

Simile al concetto di variadic in C/C++, si pensi alla printf(..).

J2SE 5: l’evoluzione di JavaLuca Ferrari 26/188

varargs: esempiopublic class varargs {

public void mvar(String...pars){for(int i=0;i<pars.length;i++){

System.out.println("Parametro "+i+" = "+pars[i]);

}}

public static void main(String argv[]){varargs v = new varargs();v.mvar(“ALFA",“BETA",“GAMMA");

}

}

L’argomento di una funzione varargs è

tramutato automaticamente in

un array.

Page 14: J2SE 5: l’evoluzione di Java · 2004. 12. 22. · 3 Luca Ferrari J2SE 5: l’evoluzione di Java 5/188 … a Tiger Nel 2004, dopo 3 anni di lavoro e due versioni beta, il JDK 1.5.0

14

J2SE 5: l’evoluzione di JavaLuca Ferrari 27/188

varargs: esempio equivalentepublic class varargs {

public void mvar(String...pars){// uso il foreachfor(String s: pars){

System.out.println(s);}

}

public static void main(String argv[]){varargs v = new varargs();v.mvar(“ALFA",“BETA",“GAMMA");

}

}

J2SE 5: l’evoluzione di JavaLuca Ferrari 28/188

varargs: output degli esempi

Parametro 0 = ALFA

Parametro 1 = BETA

Parametro 2 = GAMMA

output di esecuzione

ALFA

BETA

GAMMA

output di esecuzione

Versione con ciclo fornormale

Versione con ciclo foreach

Page 15: J2SE 5: l’evoluzione di Java · 2004. 12. 22. · 3 Luca Ferrari J2SE 5: l’evoluzione di Java 5/188 … a Tiger Nel 2004, dopo 3 anni di lavoro e due versioni beta, il JDK 1.5.0

15

J2SE 5: l’evoluzione di JavaLuca Ferrari 29/188

OverloadE’ possibile sovraccaricare un metodo varargs con una lista di argomenti dello stesso tipo.

Verrà eseguito per primo il metodo il cui prototipo corrisponde perfettamente all’invocazione!

J2SE 5: l’evoluzione di JavaLuca Ferrari 30/188

Overload: esempiopublic class varargs {public void mvar(String...pars){for(int i=0;i<pars.length;i++){

System.out.println("Parametro "+i+" = "+pars[i]);}

}

public void mvar(Object...pars){for(Object o: pars){

System.out.println("Parametro di tipo:“+o.getClass());}}

public void mvar(String s1, String s2){System.out.println("stringhe "+s1+" "+s2);}

v.mvar(“ALFA",“BETA",“GAMMA");

v.mvar("Stringa1","Stringa2");

v.mvar(new Object(), new Integer(10));

Page 16: J2SE 5: l’evoluzione di Java · 2004. 12. 22. · 3 Luca Ferrari J2SE 5: l’evoluzione di Java 5/188 … a Tiger Nel 2004, dopo 3 anni di lavoro e due versioni beta, il JDK 1.5.0

16

J2SE 5: l’evoluzione di JavaLuca Ferrari 31/188

Overload: arraySiccome il compilatore tratta i metodi varargs come metodi ad array, il sovraccarico con un array viene impedito:public class varargs {

public void mvar(String...pars){...}

public void mvar(String[] pars){

for(String s:pars){

System.out.println("String array: "+s);

}

}

}varargs.java:31: mvar(java.lang.String...) is already defined influca.varargs

public void mvar(String[] pars){

output di compilazione

J2SE 5: l’evoluzione di JavaLuca Ferrari 32/188

Single-type import

Page 17: J2SE 5: l’evoluzione di Java · 2004. 12. 22. · 3 Luca Ferrari J2SE 5: l’evoluzione di Java 5/188 … a Tiger Nel 2004, dopo 3 anni di lavoro e due versioni beta, il JDK 1.5.0

17

J2SE 5: l’evoluzione di JavaLuca Ferrari 33/188

Import StaticiL’operatore import ha ora una granularità più fine, consentendo l’unione di spazi dei nomi composti anche da soli membri, purché statici.

In altre parole, ora è possibile importare la porzione statica di una classe, utilizzandone i membri (statici) come se fossero stati dichiarati nella classe corrente.

Ciò risulta molto comodo per l’utilizzo di costanti o metodi di servizio generale, entrambi dichiarati appunto come membri statici.

J2SE 5: l’evoluzione di JavaLuca Ferrari 34/188

La nuova sintassi di importLa nuova sintassi dell’operatore import risulta ora essere la seguente:

� import package_name.class_name;

Importa la classe class_name nello spazio dei nomi corrente.

� import package_name.*;

Importa tutte le classi (*) del package package_name nello spazio dei nomi corrente.� import static package_name.class_name.member;

Importa il membro statico member della classe class_namenello spazio dei nomi corrente.� import static package_name.class_name.*;

Importa ogni membro statico della classe class_namenello spazio dei nomi corrente.

Page 18: J2SE 5: l’evoluzione di Java · 2004. 12. 22. · 3 Luca Ferrari J2SE 5: l’evoluzione di Java 5/188 … a Tiger Nel 2004, dopo 3 anni di lavoro e due versioni beta, il JDK 1.5.0

18

J2SE 5: l’evoluzione di JavaLuca Ferrari 35/188

Esempio: una classe di costantipackage fluca;

public class Constants {// definizione di una serie di membri staticipublic final static String costante1 =

"Vietato Fumare";public final static int costante2 = 30;public final static boolean costante3 = false;

public static void stampa_costanti(){System.out.println("Metodo stampa_caratteristiche");System.out.println("==>\tcostante1="+costante1);System.out.println("==>\tcostante2="+costante2);System.out.println("==>\tcostante3="+costante3);

}}

J2SE 5: l’evoluzione di JavaLuca Ferrari 36/188

Esempio: utilizzo di alcune costantipackage seminario_20;

import static fluca.Constants.costante1;import static fluca.Constants.costante2;

public class Main {

public static void main(String[] args) {

System.out.println("costante1="+costante1);

System.out.println("costante2="+costante2);

}

}

costante1=Vietato Fumarecostante2=30

output di esecuzione

Page 19: J2SE 5: l’evoluzione di Java · 2004. 12. 22. · 3 Luca Ferrari J2SE 5: l’evoluzione di Java 5/188 … a Tiger Nel 2004, dopo 3 anni di lavoro e due versioni beta, il JDK 1.5.0

19

J2SE 5: l’evoluzione di JavaLuca Ferrari 37/188

Esempio: utilizzo di alcune costantipackage seminario_20;

import static fluca.Constants.costante1;import static fluca.Constants.costante2;

public class Main {

public static void main(String[] args) {

System.out.println("costante1="+costante1);

System.out.println("costante2="+costante2);

System.out.println(“costante3=“+costante3);

}

} L’utilizzo di un membro statico non importato esplicitamente produce un errore di compilazione

Cannot find symbol:symbol : variable costante3location: class seminario_20.Main

System.out.println("costante3="+costante3);

output di compilazione

J2SE 5: l’evoluzione di JavaLuca Ferrari 38/188

Esempio: utilizzo di alcune costantipackage seminario_20;

import static fluca.Constants.costante1;import static fluca.Constants.costante2;

import static fluca.Constants.costante3;

public class Main {

public static void main(String[] args) {

System.out.println("costante1="+costante1);

System.out.println("costante2="+costante2);

System.out.println(“costante3=“+costante3);

}

}

costante1=Vietato Fumarecostante2=30costante3=false

output di esecuzione

Page 20: J2SE 5: l’evoluzione di Java · 2004. 12. 22. · 3 Luca Ferrari J2SE 5: l’evoluzione di Java 5/188 … a Tiger Nel 2004, dopo 3 anni di lavoro e due versioni beta, il JDK 1.5.0

20

J2SE 5: l’evoluzione di JavaLuca Ferrari 39/188

Esempio: importazione di metodipackage seminario_20;

import static fluca.Constants.stampa_caratteristiche;

public class Main {

public static void main(String[] args) {

System.out.println("Invoco il metodo

importato!");

stampa_caratteristiche();

}

}

Invoco il metodo importato!Metodo stampa_caratteristiche

==> costante1=Vietato Fumare==> costante2=30==> costante3=false

output di esecuzione

J2SE 5: l’evoluzione di JavaLuca Ferrari 40/188

ConflittiNel caso di membri omonimi possono nascere dei conflitti.

Se si importano membri omonimi (anche se di tipo differente) da classi diverse, nasce un errore di compilazione.

Se si importano membri omonimi di quelli definiti nella classe corrente, questi ultimi prevaricano (nascondono) quelli importati.

Page 21: J2SE 5: l’evoluzione di Java · 2004. 12. 22. · 3 Luca Ferrari J2SE 5: l’evoluzione di Java 5/188 … a Tiger Nel 2004, dopo 3 anni di lavoro e due versioni beta, il JDK 1.5.0

21

J2SE 5: l’evoluzione di JavaLuca Ferrari 41/188

Conflitti: errore di compilazionepackage seminario_20;

import static fluca.Constants.costante1;

import static fluca.Constants2.costante1;

public class Main {

public static void main(String[] args) {

System.out.println("costante1="+costante1);

}

}

Settings\luca\seminario_20\src\fluca\Constants2.java:15:<identifier> expected

public static float costante1 = 6,9;__input:8: costante1 is already defined in a single-type import(source unavailable)

output di compilazione

J2SE 5: l’evoluzione di JavaLuca Ferrari 42/188

Conflitti: prevaricamento a run-timeimport static fluca.Constants.costante1;

import static fluca.Constants.stampa_costanti;

public class Main {

public static int costante1 = 10;

public static void stampa_costanti(){

System.out.println("Nulla da stampare!");

}

public static void main(String[] args) {

System.out.println("costante1="+costante1);

stampa_costanti();

}

} costante1=10Nulla da stampare!

output di esecuzione

Page 22: J2SE 5: l’evoluzione di Java · 2004. 12. 22. · 3 Luca Ferrari J2SE 5: l’evoluzione di Java 5/188 … a Tiger Nel 2004, dopo 3 anni di lavoro e due versioni beta, il JDK 1.5.0

22

J2SE 5: l’evoluzione di JavaLuca Ferrari 43/188

enum

J2SE 5: l’evoluzione di JavaLuca Ferrari 44/188

EnumerazioniE’ stata aggiunta la parola chiave enum, che consente di definire enumerazioni on the fly.

Un’utilizzo classico è come lista static di valori.

Si presti attenzione a non confondere una enumerazione

con una serie di costanti. Seppur simili, una serie di costanti

acquisisce importanza in base al valore che si attribuisce alle stesse,

mentre una enumerazione ha importanza solo al fine di distinguere gli

elementi nella lista.

Page 23: J2SE 5: l’evoluzione di Java · 2004. 12. 22. · 3 Luca Ferrari J2SE 5: l’evoluzione di Java 5/188 … a Tiger Nel 2004, dopo 3 anni di lavoro e due versioni beta, il JDK 1.5.0

23

J2SE 5: l’evoluzione di JavaLuca Ferrari 45/188

Enumerazioni: esempiopackage seminario_20.enumerazioni;

public class EventType{

public static enum type {

OPEN,

CLOSE,

EXIT,

};

}

J2SE 5: l’evoluzione di JavaLuca Ferrari 46/188

Enumerazioni: esempiopackage seminario_20.enumerazioni;

public class Main1{

// metodo che accetta un valore enumeratopublic void fireEvent(EventType.type event){

System.out.println("L'evento ricevuto e'");

if(event == EventType.type.OPEN)System.out.println("APERTURA");

elseif(event == EventType.type.CLOSE)

System.out.println("CHIUSURA");elseif(event == EventType.type.EXIT)

System.out.println("USCITA");}

Page 24: J2SE 5: l’evoluzione di Java · 2004. 12. 22. · 3 Luca Ferrari J2SE 5: l’evoluzione di Java 5/188 … a Tiger Nel 2004, dopo 3 anni di lavoro e due versioni beta, il JDK 1.5.0

24

J2SE 5: l’evoluzione di JavaLuca Ferrari 47/188

Enumerazioni: esempiopublic static void main(String argv[]){

Main1 m = new Main1();m.fireEvent(EventType.type.OPEN);m.fireEvent(EventType.type.CLOSE);

System.out.println("Come risulta stampato? -->“+EventType.type.OPEN);

}}

L'evento ricevuto e'

APERTURA

L'evento ricevuto e'

CHIUSURA

Come risulta stampato? -->OPEN

output di esecuzione

J2SE 5: l’evoluzione di JavaLuca Ferrari 48/188

ConsiderazioniLe enumerazioni sono trattate come oggetti:

luca@linux:~/tmp/j1.5/seminario_20/enumerazioni> ls -l

total 36

-rw-r--r-- 1 luca users 306 2004-12-09 13:52 EventType.class

-rw-r--r-- 1 luca users 121 2004-12-09 13:52 EventType.java

-rw-r--r-- 1 luca users 1251 2004-12-09 13:52 EventType$type.class

-rw-r--r-- 1 luca users 1200 2004-12-09 14:09 Main1.class

-rw-r--r-- 1 luca users 629 2004-12-09 14:09 Main1.java

L’enumerazione viene trattata come inner class.

Page 25: J2SE 5: l’evoluzione di Java · 2004. 12. 22. · 3 Luca Ferrari J2SE 5: l’evoluzione di Java 5/188 … a Tiger Nel 2004, dopo 3 anni di lavoro e due versioni beta, il JDK 1.5.0

25

J2SE 5: l’evoluzione di JavaLuca Ferrari 49/188

Che tipo di oggetto è un’enumerazione?public void fireEvent(EventType.type event){

...// analizzo la classe dell'eventoClass clazz = event.getClass();System.out.println("Nome della classe di evento: “

+clazz.getName());for(Field f: clazz.getFields()){

System.out.println("Campo: "+f.getName());System.out.println("\t visibilita': ");int modificatore = f.getModifiers();if(Modifier.isPublic(modificatore)){

System.out.println("\tpubblico");}else if(Modifier.isPrivate(modificatore)){

System.out.println("\tprivato");}

}}

J2SE 5: l’evoluzione di JavaLuca Ferrari 50/188

Che tipo di oggetto è un’enumerazione?

Nome della classe di evento:seminario_20.enumerazioni.EventType$type

Campo: OPEN

visibilita':

pubblico

Campo: CLOSE

visibilita':

pubblico

Campo: EXIT

visibilita':

pubblico

output di esecuzione

Page 26: J2SE 5: l’evoluzione di Java · 2004. 12. 22. · 3 Luca Ferrari J2SE 5: l’evoluzione di Java 5/188 … a Tiger Nel 2004, dopo 3 anni di lavoro e due versioni beta, il JDK 1.5.0

26

J2SE 5: l’evoluzione di JavaLuca Ferrari 51/188

Output Formattato

J2SE 5: l’evoluzione di JavaLuca Ferrari 52/188

L’output formattatoLe classi di output su stream (ad es. PrintStream) di Java hanno il pregio di avere un utilizzo molto semplice ed immediato, ma non consentono un elevato controllo sull’output effettivo.

Altri linguaggi, come ad esempio il C/C++ consentono un accurato controllo dell’output mediante l’uso delle funzioni appartenenti alla famiglia printf.

Page 27: J2SE 5: l’evoluzione di Java · 2004. 12. 22. · 3 Luca Ferrari J2SE 5: l’evoluzione di Java 5/188 … a Tiger Nel 2004, dopo 3 anni di lavoro e due versioni beta, il JDK 1.5.0

27

J2SE 5: l’evoluzione di JavaLuca Ferrari 53/188

Differenze fra i metodi Java e printfI metodi println(..) di un PrintStream Java sono i più usati per l’output formattato su stream. Le differenze fra tali metodi e la printf(..) del C/C++ sono le seguenti:� printf è una funzione variadic, println no;� printf richiede come primo argomento una stringa di formato, seguita dai parametri da convertire in stringa. println consente di inserire il parametro da stampare direttamente nella posizione in cui deve essere stampato (utilizzo dell’operatore + su stringa);� printf ha una implementazione unica indipendentemente dal tipo e numero di argomenti che deve gestire, println è sovraccaricato per ogni lista di parametri differente;� printf consente di specificare la lunghezza dei valori, println richiede l’utilizzo di operazioni di substringing.

J2SE 5: l’evoluzione di JavaLuca Ferrari 54/188

Il ritorno della printfPer sopperire alle lacune di formattazione, alcune classi di libreria sono state estese: String, PrintWriter e PrintStream hanno acquisito ciascuna i seguenti metodi (varargs):

format(String format, Object... args);

printf(String format, Object... args);

format(Locale locale, String format,Object... args);

printf(Locale locale, String format,

Object... args);

Page 28: J2SE 5: l’evoluzione di Java · 2004. 12. 22. · 3 Luca Ferrari J2SE 5: l’evoluzione di Java 5/188 … a Tiger Nel 2004, dopo 3 anni di lavoro e due versioni beta, il JDK 1.5.0

28

J2SE 5: l’evoluzione di JavaLuca Ferrari 55/188

Esempio: printfpublic class Main {

public static void main(String[] args) {int v1 = 10;float v2 = (float)3.69;String v3 = "Ciao";System.out.printf("valori: v1=%d v2=%f

v3=%s\n",v1,v2,v3);

String s = String.format("valori: v1=%d v2=%fv3=%s",v1,v2,v3);

System.out.println(s);}

}

valori: v1=10 v2=3,690000 v3=Ciaovalori: v1=10 v2=3,690000 v3=Ciao

output di esecuzione

J2SE 5: l’evoluzione di JavaLuca Ferrari 56/188

ArgomentiStoria

(da OAK a J2SE 5)

Novità sintattiche

(boxing, foreach, varargs, static import, enum, output formattato)

Novità semantiche

(generics, annotazioni, tipo di ritorno variabili)

Classi aggiunte o modificate

(Swing, StackTraceElement, InetAdress, Management Factory, …)

Varie

(Pack200, Ergonomics, …)

Risorse

Page 29: J2SE 5: l’evoluzione di Java · 2004. 12. 22. · 3 Luca Ferrari J2SE 5: l’evoluzione di Java 5/188 … a Tiger Nel 2004, dopo 3 anni di lavoro e due versioni beta, il JDK 1.5.0

29

J2SE 5: l’evoluzione di JavaLuca Ferrari 57/188

Generics

J2SE 5: l’evoluzione di JavaLuca Ferrari 58/188

type-safeProblema: garantire a compile time la coerenza dei dati di una collezione.

Il problema, noto come “type-safe”, richiede la capacità di usare strutture ed algoritmi generali specializzandoli al volo.

Non è banale!

Il controllo di tipo avviene sicuramente a run-time, ma potrebbe essere troppo tardi!

Page 30: J2SE 5: l’evoluzione di Java · 2004. 12. 22. · 3 Luca Ferrari J2SE 5: l’evoluzione di Java 5/188 … a Tiger Nel 2004, dopo 3 anni di lavoro e due versioni beta, il JDK 1.5.0

30

J2SE 5: l’evoluzione di JavaLuca Ferrari 59/188

Quando la conformità può creare problemi…

Mediante la conformità è possibile usare le sottoclassi come fossero classi base.

Ciò produce indubbi vantaggi, consentendo di utilizzare lo stesso algoritmo per tutte le classi derivate.

Si pensi ad esempio alle strutture dati Java (ad es. Vector), che sono progettate per accettare qualunque tipo di oggetto…

La conformità può creare problemi di type-safe.

J2SE 5: l’evoluzione di JavaLuca Ferrari 60/188

Un esempio concretoLa soluzione si ha usando i tipi parametrizzati (chiamati in Java generics).Per meglio comprendere, si farà uso del seguente esempio:

� si dispone di due tipi di persone: studenti e professori;� si deve costruire un archivio capace di contenere sia studenti che professori;� l’archivio deve essere omogeneo (non si devono mischiare professori con studenti e vice versa).

Page 31: J2SE 5: l’evoluzione di Java · 2004. 12. 22. · 3 Luca Ferrari J2SE 5: l’evoluzione di Java 5/188 … a Tiger Nel 2004, dopo 3 anni di lavoro e due versioni beta, il JDK 1.5.0

31

J2SE 5: l’evoluzione di JavaLuca Ferrari 61/188

Un esempio concreto: implementazione della gerarchia

Studenti e professori sono accomunati dal fatto di essere entrambi persone; inoltre si deve costruire una logica uguale per entrambe le specializzazioni.

Ciò porta alla realizzazione di un legame fra studenti e professori:

una gerarchia!

Persona

Professore Studente

J2SE 5: l’evoluzione di JavaLuca Ferrari 62/188

Un esempio concreto: implementazione della gerarchia

package seminario_20.generics;

public class Persona {

protected String nome, cognome;

protected int eta;

public Persona(String nome, String cognome,

int eta){this.nome = nome;

this.cognome = cognome;

this.eta = eta;

}

Persona

Professore Studente

Page 32: J2SE 5: l’evoluzione di Java · 2004. 12. 22. · 3 Luca Ferrari J2SE 5: l’evoluzione di Java 5/188 … a Tiger Nel 2004, dopo 3 anni di lavoro e due versioni beta, il JDK 1.5.0

32

J2SE 5: l’evoluzione di JavaLuca Ferrari 63/188

Un esempio concreto: implementazione della gerarchiapublic String toString(){

return nome+" "+cognome+" "+eta;}

} // fine della classe Persona

Persona

Professore Studente

J2SE 5: l’evoluzione di JavaLuca Ferrari 64/188

Un esempio concreto: implementazione della gerarchia

package seminario_20.generics;

public class Professore extends Persona{

public Professore(String nome,

String cognome,

int eta) {

super(nome,cognome,eta);

}

public String toString(){

return nome+" "+cognome+" "+eta+

" - professore";

}

}Persona

Professore Studente

Page 33: J2SE 5: l’evoluzione di Java · 2004. 12. 22. · 3 Luca Ferrari J2SE 5: l’evoluzione di Java 5/188 … a Tiger Nel 2004, dopo 3 anni di lavoro e due versioni beta, il JDK 1.5.0

33

J2SE 5: l’evoluzione di JavaLuca Ferrari 65/188

Un esempio concreto: implementazione della gerarchia

package seminario_20.generics;

public class Studente extends Persona{

public Studente(String nome,

String cognome,

int eta) {

super(nome,cognome,eta);

}

}

Persona

Professore Studente

J2SE 5: l’evoluzione di JavaLuca Ferrari 66/188

Un esempio concreto: l’implementazione dell’archivio

package seminario_20.generics;import java.util.Vector;public class Archivio1 {

protected Vector persone;

public Archivio1() {persone = new Vector(10);

}

public void aggiungi(Persona p){persone.add(p);

}

public void rimuovi(Persona p){persone.remove(p);

}

Page 34: J2SE 5: l’evoluzione di Java · 2004. 12. 22. · 3 Luca Ferrari J2SE 5: l’evoluzione di Java 5/188 … a Tiger Nel 2004, dopo 3 anni di lavoro e due versioni beta, il JDK 1.5.0

34

J2SE 5: l’evoluzione di JavaLuca Ferrari 67/188

public Persona get(int index){return (Persona)persone.get(index);

}

public int size(){return persone.size();

}

} // fine della classe Archivio1

Un esempio concreto: l’implementazione dell’archivio

J2SE 5: l’evoluzione di JavaLuca Ferrari 68/188

Il problema di Archivio1La classe Archivio1 gestisce (con una sola logica) tutti i tipi Persona; ciò può provocare type-unsafety.In altre parole non vi è nessun meccanismo che controlli il tipo (specifico) dei dati inseriti/rimossi dall’archivio.

Cosa ancora più importante: le incoerenze non possono essere rilevate a tempo di

compilazione !(si ricordi che Studente e Professore sono sottoclassi di Persona)

Page 35: J2SE 5: l’evoluzione di Java · 2004. 12. 22. · 3 Luca Ferrari J2SE 5: l’evoluzione di Java 5/188 … a Tiger Nel 2004, dopo 3 anni di lavoro e due versioni beta, il JDK 1.5.0

35

J2SE 5: l’evoluzione di JavaLuca Ferrari 69/188

Un utilizzo scorrettopublic static void main(String argv[]){

// creazione di studenti e professoriStudente s1 =

new Studente("Luca","Ferrari",26);Studente s2 =

new Studente("Santi","Caballe",29);Studente s3 =

new Studente("James","Gosling",50);Professore pr1 =

new Professore("Silvia","Rossi",27);Professore pr2 =

new Professore("Simon","Ritter", 40);

// creazione di due archivi separatiArchivio1 archivio_prof = new Archivio1();Archivio1 archivio_stud = new Archivio1();

J2SE 5: l’evoluzione di JavaLuca Ferrari 70/188

Un utilizzo scorretto// aggiungo i prof e gli studenti ai relativi// archiviarchivio_prof.aggiungi(pr1);archivio_prof.aggiungi(pr2);archivio_prof.aggiungi(s1);

archivio_stud.aggiungi(s1);archivio_stud.aggiungi(s2);archivio_stud.aggiungi(s3);archivio_stud.aggiungi(pr1);

Disastro imminente!

Disastro imminente!

Oggetti di tipo incoerente sono stati aggiunti agli archivi. Il compilatore e il sistema run-time non possono rilevare

questo errore di logica, essendo l’archivio basato sulla superclasse dei tipi realmente utilizzati.

Page 36: J2SE 5: l’evoluzione di Java · 2004. 12. 22. · 3 Luca Ferrari J2SE 5: l’evoluzione di Java 5/188 … a Tiger Nel 2004, dopo 3 anni di lavoro e due versioni beta, il JDK 1.5.0

36

J2SE 5: l’evoluzione di JavaLuca Ferrari 71/188

Un utilizzo scorretto

// stampa professorifor(int i=0;i<archivio_prof.size();i++){

Professore pTemp =(Professore)archivio_prof.get(i);

System.out.println("Professore "+i+" "+pTemp);

}

// stampa studentifor(int i=0;i<archivio_stud.size();i++){

Studente sTemp =(Studente)archivio_stud.get(i);

System.out.println("Studente "+i+" "+sTemp);

}} // fine del metodo main

J2SE 5: l’evoluzione di JavaLuca Ferrari 72/188

Un utilizzo scorretto

Professore 0 Silvia Rossi 27 – professore

Professore 1 Simon Ritter 40 - professore

Exception in thread "main“ java.lang.ClassCastException:

seminario_20.generics.Studente

at seminario_20.generics.Main1.main(Main1.java:32)

output di esecuzione

Il problema risiede nel cast fatto al momento dell’estrazione dall’archivio:Professore pTemp = (Professore)archivio_prof.get(i);

L’assunzione è corretta: l’archivio dei professori (studenti) dovrebbe contenere solo professori (studenti), quindi il cast esplicito è lecito.

Page 37: J2SE 5: l’evoluzione di Java · 2004. 12. 22. · 3 Luca Ferrari J2SE 5: l’evoluzione di Java 5/188 … a Tiger Nel 2004, dopo 3 anni di lavoro e due versioni beta, il JDK 1.5.0

37

J2SE 5: l’evoluzione di JavaLuca Ferrari 73/188

Possibili soluzioni (in ordine di disperazione)

1. realizzare una forma di archivio specifica per ogni tipo di dato presente.Ad esempio, realizzando un archivio che accetti come dato un Professore, non si potrà correre il rischio di inserirvi uno Studente.

Questa soluzione risulta valida nel breve termine, ma non accettabile nel lungo periodo, essendo incapace di gestire correttamente il code refactoring. Ogni volta che un nuovo tipo viene inserito, un nuovo archivio deve essere implementato.

Persona

Professore Studente

Tecnico

J2SE 5: l’evoluzione di JavaLuca Ferrari 74/188

Possibili soluzioni (in ordine di disperazione)

2. utilizzare interfacce differenti per ogni archivio.Definendo una interfaccia per ogni archivio, e “costringendo” l’archivio ad implementarle entrambe, si ottiene una soluzione molto ObjectOriented, abbastanza sicura e sicuramente flessibile, al costo di una minima aggiunta di codice.

Page 38: J2SE 5: l’evoluzione di Java · 2004. 12. 22. · 3 Luca Ferrari J2SE 5: l’evoluzione di Java 5/188 … a Tiger Nel 2004, dopo 3 anni di lavoro e due versioni beta, il JDK 1.5.0

38

J2SE 5: l’evoluzione di JavaLuca Ferrari 75/188

Possibili soluzioni (in ordine di disperazione)

2. utilizzare interfacce differenti per ogni archivio.

public inteface archivio_studenti{

public void aggiungi(Studente s);

...

}

public interface archivio_professori{

public void aggiungi(Professore p);

}

public class Archivio

implements archivio_studenti, archivio_professori

{...}

J2SE 5: l’evoluzione di JavaLuca Ferrari 76/188

Possibili soluzioni (in ordine di disperazione)

2. utilizzare interfacce differenti per ogni archivio.

I problemi di questa soluzione:a) è potenzialmente non type-safe, essendo

comunque possibile scavalcare le interfacce per lavorare direttamente sull’archivio;

b) come per la soluzione precedente, ogni volta che un nuovo tipo viene aggiunto, l’archivio deve essere modificato di conseguenza.

Page 39: J2SE 5: l’evoluzione di Java · 2004. 12. 22. · 3 Luca Ferrari J2SE 5: l’evoluzione di Java 5/188 … a Tiger Nel 2004, dopo 3 anni di lavoro e due versioni beta, il JDK 1.5.0

39

J2SE 5: l’evoluzione di JavaLuca Ferrari 77/188

Possibili soluzioni (in ordine di disperazione)

3. fornire un parametro all’archivio che imponga il tipo di istanza da gestire.

public Archivio1(Class clazz){

this.managedType = clazz;

}

public void aggiungi_persona(Persona p) throws Exception{

if( managedType != null &&

(p.getClass()!= managedType ) ){

throw new Exception(“Tipo sbagliato”);

}

// inserimento dell’argomento…

}

Anticipa ciò che avviene a run-timeper un cast incorretto!

J2SE 5: l’evoluzione di JavaLuca Ferrari 78/188

Possibili soluzioni (in ordine di disperazione)

4. eliminare la gerarchia.

Non è una soluzione Object Oriented!

Produce la scrittura di molto codice in più.

Page 40: J2SE 5: l’evoluzione di Java · 2004. 12. 22. · 3 Luca Ferrari J2SE 5: l’evoluzione di Java 5/188 … a Tiger Nel 2004, dopo 3 anni di lavoro e due versioni beta, il JDK 1.5.0

40

J2SE 5: l’evoluzione di JavaLuca Ferrari 79/188

GenericsE’ ora possibile un controllo accurato sui tipi a tempo di compilazione, ma le strutture dati devono essere progettate come tipi parametrici(generics).

Una classe che sfrutti generics non ha un tipo di dato predefinito, ma lo riceve a tempo di istanziazione.

J2SE 5: l’evoluzione di JavaLuca Ferrari 80/188

GenericsIn altre parole, con generics, è possibile costruire classi con algoritmi standard e capaci di agire su più tipi di dati, ma in modo coerente.

“From the perspective of both software engineering and programming pedagogy, Java has a crude type system. Its mostsignificant failing is the lack of support for generic types.”

(Erica Allen, Safe Instantiation in Generic Java,

PPPJ 2004)

La sintassi di generics fa uso delle parentesi angolari (<,>) per indicare un tipo da specificare in seguito.

Page 41: J2SE 5: l’evoluzione di Java · 2004. 12. 22. · 3 Luca Ferrari J2SE 5: l’evoluzione di Java 5/188 … a Tiger Nel 2004, dopo 3 anni di lavoro e due versioni beta, il JDK 1.5.0

41

J2SE 5: l’evoluzione di JavaLuca Ferrari 81/188

Usando generics…package seminario_20.generics;import java.util.Vector;

public class Archivio2<E> {protected Vector persone;

public Archivio2() {persone = new Vector(10);

}

public void aggiungi(E p){persone.add(p);

}

public void rimuovi(E p){persone.remove(p);

}

Con questa dichiarazione si

indica che l’identificatore E fa riferimento ad un

tipo di dato che sarà specificato nel

codice che userà Archivio2.

I metodi ora fanno riferimento a

variabili di tipo E.

J2SE 5: l’evoluzione di JavaLuca Ferrari 82/188

Usando generics…

public E get(int index){return (E)persone.get(index);

}

public int size(){return persone.size();

}

} // fine della classe Archivio2

Page 42: J2SE 5: l’evoluzione di Java · 2004. 12. 22. · 3 Luca Ferrari J2SE 5: l’evoluzione di Java 5/188 … a Tiger Nel 2004, dopo 3 anni di lavoro e due versioni beta, il JDK 1.5.0

42

J2SE 5: l’evoluzione di JavaLuca Ferrari 83/188

public static void main(String argv[]){...

Archivio2<Professore> archivio_prof =new Archivio2<Professore>();

Archivio2<Studente> archivio_stud =new Archivio2<Studente>();

Archivio2<Persona> archivio_per =new Archivio2<Persona>();

archivio_prof.aggiungi(pr1);archivio_prof.aggiungi(pr2);archivio_prof.aggiungi(s1);...

}

Usando generics…

Main2.java:34: aggiungi(seminario_20.generics.Studente) inseminario_20.generics.Archivio2<seminario_20.generics.Studente>cannot be applied to (seminario_20.generics.Professore)

output di compilazione

J2SE 5: l’evoluzione di JavaLuca Ferrari 84/188

I vantaggi di genericsLe incoerenze di tipo sono rilevate a tempo di compilazione, e non a tempo di esecuzione, aiutando il programmatore nel trovare errori di logica.

Si noti che generics non impedisce di usare la gerarchia mischiando i tipi, ma semplicemente richiede che si sia coscienti di ciò che si sta facendo:Archivio2<Persona> archivio_per =

new Archivio2<Persona>();

Page 43: J2SE 5: l’evoluzione di Java · 2004. 12. 22. · 3 Luca Ferrari J2SE 5: l’evoluzione di Java 5/188 … a Tiger Nel 2004, dopo 3 anni di lavoro e due versioni beta, il JDK 1.5.0

43

J2SE 5: l’evoluzione di JavaLuca Ferrari 85/188

WildcardsGenerics ammette l’uso del carattere ‘?’ come speciale wildcard, con i seguenti significati:

� <?> indica tutti i tipi della classe cui si fa riferimento. Ad esempio Archivio2<?> indica sia Archivio2<Studente> che Archivio2<Professore>;� <? extends type> indica tutti i tipi che ereditano da type. Ad esempio Archivio2<? extendsPersona> indica tutti i tipi di Archivio2parametrizzati da Persona;� <? super type> simile al caso precedente, ma tratta superclassi.

J2SE 5: l’evoluzione di JavaLuca Ferrari 86/188

Specializzare una classe con generics

E’ possibile ereditare da una classe e aggiungere, nel contempo, il supporto a generics, facendo però attenzione affinché i metodi non siano in conflitto.

package seminario_20.generics;

public class Archivio3<E> extends Archivio1{

public void aggiungiElement(E p){

persone.add(p);

}

...

}

ATTENZIONE: si ricordi che Studente (Professore) è anche Persona, quindi un metodo aggungi(E p)

potrebbe andare in conflitto con Archivio1#aggiungi(Persona p) qualora il tipo sia

ancora una Persona.

Page 44: J2SE 5: l’evoluzione di Java · 2004. 12. 22. · 3 Luca Ferrari J2SE 5: l’evoluzione di Java 5/188 … a Tiger Nel 2004, dopo 3 anni di lavoro e due versioni beta, il JDK 1.5.0

44

J2SE 5: l’evoluzione di JavaLuca Ferrari 87/188

Cosa c’è dietro a genericsLa magia di generics risiede nel nuovo sistema di compilazione.

Il compilatore effettua ora alcuni passi di manipolazione sintattica (type erasurers) al fine di forzare eventuali errori di casting.

J2SE 5: l’evoluzione di JavaLuca Ferrari 88/188

Generics in azione: codice utilizzatoIl tag di generics viene rimosso, e il codice viene compilato sostituendo al tipo parametrico Object.

public class Archivio2<E> {

protected Vector persone;

public Archivio2() {

persone = new Vector(10);

}

public void aggiungi(E p){

persone.add(p);

}

public void rimuovi(E p){

persone.remove(p);

}

public class Archivio2 {

protected Vector persone;

public Archivio2() {

persone = new Vector(10);

}

public void aggiungi(Object p){

persone.add(p);

}

public void rimuovi(Object p){

persone.remove(p);

}

Page 45: J2SE 5: l’evoluzione di Java · 2004. 12. 22. · 3 Luca Ferrari J2SE 5: l’evoluzione di Java 5/188 … a Tiger Nel 2004, dopo 3 anni di lavoro e due versioni beta, il JDK 1.5.0

45

J2SE 5: l’evoluzione di JavaLuca Ferrari 89/188

Generics in azione: codice utilizzatoreIl compilatore rimuove i tag di generics, e “forza” dei cast.

public static void main(String argv[]){...

Archivio2<Professore> archivio_prof =new Archivio2<Professore>();

Archivio2<Studente> archivio_stud =new Archivio2<Studente>();

Archivio2<Persona> archivio_per =new Archivio2<Persona>();

archivio_prof.aggiungi(pr1);archivio_prof.aggiungi(pr2);archivio_prof.aggiungi(s1);...

}

public static void main(String argv[]){...

Archivio2 archivio_prof =new Archivio2 ();

Archivio2 archivio_stud =new Archivio2 ();

Archivio2 archivio_per =new Archivio2 ();

archivio_prof.aggiungi((Professore)pr1);archivio_prof.aggiungi((Professore)pr2);archivio_prof.aggiungi((Professore)s1);...

}

J2SE 5: l’evoluzione di JavaLuca Ferrari 90/188

Generics e il resto del mondoLa libreria Java supporta appieno generics:public static void main(String argv[]){

Vector<String> vettore = new Vector<String>();

for(int i=0;i<10;i++){

vettore.add(new String("stringa n."+i));

}

for(String s: vettore){

System.out.println(s);

}

}

Quando usato con generics, foreach lavora sul tipo di dato corretto!

Page 46: J2SE 5: l’evoluzione di Java · 2004. 12. 22. · 3 Luca Ferrari J2SE 5: l’evoluzione di Java 5/188 … a Tiger Nel 2004, dopo 3 anni di lavoro e due versioni beta, il JDK 1.5.0

46

J2SE 5: l’evoluzione di JavaLuca Ferrari 91/188

Ma non tutto è generics!Se si tenta di utilizzare una classe “normale” come fosse generics, si ottiene un errore di compilazione.

Archivio1<Professore> = new Archivio1<Professore>();

Main4.java:15: not a statement

Archivio1<Professore> = new Archivio1<Professore>();

Main4.java:15: ';' expected

Archivio1<Professore> = new Archivio1<Professore>();

output di compilazione

J2SE 5: l’evoluzione di JavaLuca Ferrari 92/188

Il rovescio della medagliaGenerics consente di usare un algoritmo generico in type-safe, ma per impostazione predefinita non impedisce di usare l’algoritmo per istanze diverse da quelle per cui questo è stato progettato (cosa impedita dalla conformità)!

Archivio2<String> = new Archivio2<String>();

La ragione di ciò risiede nel modo in cui la classe sottoposta a generics viene compilata: tutti gli identificatori sono sostituiti con Object.

E’ possibile limitare i tipi utilizzabili!

Page 47: J2SE 5: l’evoluzione di Java · 2004. 12. 22. · 3 Luca Ferrari J2SE 5: l’evoluzione di Java 5/188 … a Tiger Nel 2004, dopo 3 anni di lavoro e due versioni beta, il JDK 1.5.0

47

J2SE 5: l’evoluzione di JavaLuca Ferrari 93/188

Limitare l’uso dei tipipublic class Archivio2<E extends Persona>{…}

Se a questo punto si tenta di creare un archivio con un tipo sbagliato, si ottiene un errore di compilazione.

Archivio2<String> archivio_stud =

new Archivio2<String>();

seminario_20\generics\Main9.java:13: type parameterjava.lang.String is not within its bound

Archivio2<String> archivio_stud =

new Archivio2<String>();

output di compilazione

J2SE 5: l’evoluzione di JavaLuca Ferrari 94/188

Generics non implica relazioni!Tutte le istanze create in modo parametrizzato condividono la stessa classe.

Archivio2<Persona> aPersona = …

Archivio2<Studente> aStudente = …

Non sono in relazione! (anche se Studente eredita da Persona)

Page 48: J2SE 5: l’evoluzione di Java · 2004. 12. 22. · 3 Luca Ferrari J2SE 5: l’evoluzione di Java 5/188 … a Tiger Nel 2004, dopo 3 anni di lavoro e due versioni beta, il JDK 1.5.0

48

J2SE 5: l’evoluzione di JavaLuca Ferrari 95/188

Generics extends GenericsE’ possibile estendere una classe che fa uso di generics, la sottoclasse può a sua volta fare uso di generics.

Valgono tutte le regole dell’ereditarietà (es. overriding)!

Esempio: estendere l’archivio visto in precedenza (Archivio2) in modo che possa memorizzare associazioni Studente-Professore in type-safe.

J2SE 5: l’evoluzione di JavaLuca Ferrari 96/188

Esempiopackage seminario_20.generics;import java.util.Hashtable;

public class Archivio5<E,R> extends Archivio2<E>{// relazioniprotected Hashtable relazioni;

public Archivio5(){super();relazioni = new Hashtable();

}

public void aggiungiRelazione(E p1, R p2){relazioni.put(p1,p2);

}

Page 49: J2SE 5: l’evoluzione di Java · 2004. 12. 22. · 3 Luca Ferrari J2SE 5: l’evoluzione di Java 5/188 … a Tiger Nel 2004, dopo 3 anni di lavoro e due versioni beta, il JDK 1.5.0

49

J2SE 5: l’evoluzione di JavaLuca Ferrari 97/188

Esempiopublic void stampaRelazioni(){

Enumeration<E> chiavi = relazioni.keys();

while(chiavi.hasMoreElements()){E chiave = chiavi.nextElement();System.out.println("Relazione "+chiave+" - “

+relazioni.get(chiave));}

}

}

J2SE 5: l’evoluzione di JavaLuca Ferrari 98/188

Esempio: utilizzopackage seminario_20.generics;

public class Main5{public static void main(String argv[]){

Studente s1 =new Studente("Luca","Ferrari",26);

Studente s2 =new Studente("Santi","Caballe",29);

Studente s3 =new Studente("James","Gosling",50);

Professore pr1 =new Professore("Silvia","Rossi",37);

Professore pr2 =new Professore("S.","Ritter", 40);

Page 50: J2SE 5: l’evoluzione di Java · 2004. 12. 22. · 3 Luca Ferrari J2SE 5: l’evoluzione di Java 5/188 … a Tiger Nel 2004, dopo 3 anni di lavoro e due versioni beta, il JDK 1.5.0

50

J2SE 5: l’evoluzione di JavaLuca Ferrari 99/188

Esempio: utilizzoArchivio5<Studente,Professore> archivio =

new Archivio5<Studente,Professore>();

archivio.aggiungi(s1);archivio.aggiungi(s2);archivio.aggiungi(s3);

archivio.aggiungiRelazione(s1,pr1);archivio.aggiungiRelazione(s2,pr2);

archivio.stampaRelazioni();}

} // fine della classe

Relazione Luca Ferrari 26 - Silvia Rossi 37 - professore

Relazione Santi Caballe 29 – S. Ritter 40 - professore

output di esecuzione

J2SE 5: l’evoluzione di JavaLuca Ferrari 100/188

Considerazioni sull’esempio� E’ possibile utilizzare generics con più di un tipo di parametro:public class Archivio5<E,R> extends Archivio2<E>{...}

Archivio5<Studente,Professore> archivio = new

Archivio5<Studente,Professore>();

� Il type-safe è garantito:archivio.aggiungi(pr1);

archivio.aggiungiRelazione(pr1,s1);

seminario_20/generics/Main5.java:17: aggiungi(seminario_20.generics.Studente) inseminario_20.generics.Archivio2<seminario_20.generics.Studente> cannot be appliedto (seminario_20.generics.Professore)

archivio.aggiungi(pr1);

^

seminario_20/generics/Main5.java:20:aggiungiRelazione(seminario_20.generics.Studente,seminario_20.generics.Professore)inseminario_20.generics.Archivio5<seminario_20.generics.Studente,seminario_20.generics.Professore> cannot be applied to(seminario_20.generics.Professore,seminario_20.generics.Studente)

archivio.aggiungiRelazione(pr1,s1);

output di compilazione

Page 51: J2SE 5: l’evoluzione di Java · 2004. 12. 22. · 3 Luca Ferrari J2SE 5: l’evoluzione di Java 5/188 … a Tiger Nel 2004, dopo 3 anni di lavoro e due versioni beta, il JDK 1.5.0

51

J2SE 5: l’evoluzione di JavaLuca Ferrari 101/188

Templates? No grazie!Anche se molto simili nella sintassi e nell’utilizzo, i Java generics non sono la stessa cosa dei template C++.

I template C++ si riconducono a macro del preprocessore, che producono il codice sorgente di una nuova classe con i tipi “fissati”.

Generics opera a livello di compilatore e non “sporca” il codice della classe che si sta utilizzando.

Generics è un modo di concepire e scrivere software!

J2SE 5: l’evoluzione di JavaLuca Ferrari 102/188

General PurposeAnnotations

Page 52: J2SE 5: l’evoluzione di Java · 2004. 12. 22. · 3 Luca Ferrari J2SE 5: l’evoluzione di Java 5/188 … a Tiger Nel 2004, dopo 3 anni di lavoro e due versioni beta, il JDK 1.5.0

52

J2SE 5: l’evoluzione di JavaLuca Ferrari 103/188

AnnotazioniUna annotazione è un’informazione associata ad un frammento di codice.

Le annotazioni non cambiano direttamente la semantica del codice cui sono applicate, ma influenzano l’esecuzione di strumenti che utilizzano tale codice (e quindi ne modificano la semantica!).

J2SE 5: l’evoluzione di JavaLuca Ferrari 104/188

Annotazioni in JavaJava supporta le annotazioni fin dalla versione 1.0.

Esempi di annotazioni sono:� transient: indica al sistema di serializzazione di non salvare su stream il campo� i tag javadoc (@param, @since, …)

Quindi cosa c’è di nuovo?

Page 53: J2SE 5: l’evoluzione di Java · 2004. 12. 22. · 3 Luca Ferrari J2SE 5: l’evoluzione di Java 5/188 … a Tiger Nel 2004, dopo 3 anni di lavoro e due versioni beta, il JDK 1.5.0

53

J2SE 5: l’evoluzione di JavaLuca Ferrari 105/188

Annotazioni in JavaGli esempi di annotazioni di prima sono specifici per un solo scopo (serializzazione, documentazione,…).

E’ ora possibile realizzare annotazioni general purpose, utilizzabili in diversi contesti e per scopi differenti.

Ciò aumenta le possibilità di gestione del codice, semplificando lo sviluppo in team, l’analisi del codice, la realizzazione di regression-test, …

J2SE 5: l’evoluzione di JavaLuca Ferrari 106/188

Era necessario?Prima dell’avvento di J2SE 5, era comunque possibile usare annotazioni general purpose.

Si dovevano però utilizzare file di proprietà, file XML (deployment) o altro,costringendo i programmatori a far fronte a sistemi eterogenei.

Ora è possibile realizzare annotazioni in Java, creare librerie di annotazioni,….

Page 54: J2SE 5: l’evoluzione di Java · 2004. 12. 22. · 3 Luca Ferrari J2SE 5: l’evoluzione di Java 5/188 … a Tiger Nel 2004, dopo 3 anni di lavoro e due versioni beta, il JDK 1.5.0

54

J2SE 5: l’evoluzione di JavaLuca Ferrari 107/188

Quindi un’annotazione Java è� una classe che contiene membri descrittivi (note); � associabile a membri Java (classi, metodi, variabili) senza influenzarne il comportamento;� associabile ad una fase di vita del codice (compilazione, esecuzione);� analizzabile da altro codice Java (eventualmente tramite reflection).

J2SE 5: l’evoluzione di JavaLuca Ferrari 108/188

Annotazioni Java: definizioneUna annotazione viene definita in modo

simile ad una interfaccia.

La definizione di una annotazione prevede che:

1. vi si riferisca facendo precedere il carattere ‘@’ alla parola interface;

2. non vi siano variabili;3. vi siano metodi senza corpo, con valori

di ritorno standard (int, boolean, String, …);

Page 55: J2SE 5: l’evoluzione di Java · 2004. 12. 22. · 3 Luca Ferrari J2SE 5: l’evoluzione di Java 5/188 … a Tiger Nel 2004, dopo 3 anni di lavoro e due versioni beta, il JDK 1.5.0

55

J2SE 5: l’evoluzione di JavaLuca Ferrari 109/188

Esempio di definizioneDefinizione di una annotazione che contenga versione, note, autore di un frammento di codice.

Occorre quindi definire una annotazione con i seguenti membri (metodi che fungono da campi!):� nota, di tipo String� stabile, di tipo boolean, indica se il codice è da considerarsi stabile o affetto da bug� ultimo_autore, di tipo String, il nome dell’ultimo autore� versione, di tipo int

J2SE 5: l’evoluzione di JavaLuca Ferrari 110/188

Esempio di definizioneimport java.lang.annotation.*;

@Retention(RetentionPolicy.RUNTIME)

@Target(ElementType.METHOD)

public @interface Check {

int versione(); // numero di versione

boolean stabile(); // ha dei bug?

String nota(); // nota di testo

String ultimo_autore(); // ultimo autore

}

Package introdotto per le annotazioni.

Indicano a che “istante di vita” si

applica l’annotazione (RUNTIME) e a che

elementi (METHOD).Una interfaccia speciale!

Simili a metodi astratti (niente corpo).

Page 56: J2SE 5: l’evoluzione di Java · 2004. 12. 22. · 3 Luca Ferrari J2SE 5: l’evoluzione di Java 5/188 … a Tiger Nel 2004, dopo 3 anni di lavoro e due versioni beta, il JDK 1.5.0

56

J2SE 5: l’evoluzione di JavaLuca Ferrari 111/188

Alcune note sulla definizioneLe annotazione possono essere annotate!

Una annotazione che ne annota un’altra è dette meta-annotazione. Alcuni esempi sono:

@Retention(RetentionPolicy.RUNTIME)

@Target(ElementType.METHOD)

J2SE 5: l’evoluzione di JavaLuca Ferrari 112/188

Utilizzo di una annotazioneLe regole per l’utilizzo di una annotazione sono:� alla ”creazione”, vi si riferisce con il nome dato preceduto dal carattere ‘@’;� il valore dei membri (rappresentati dai metodi!) sono assegnati mediante sintassi

nome = valore

� l’utilizzo avviene tramite cast esplicito (come per un normale oggetto); i valori dell’annotazione sono estratti invocando i metodi definiti.

Page 57: J2SE 5: l’evoluzione di Java · 2004. 12. 22. · 3 Luca Ferrari J2SE 5: l’evoluzione di Java 5/188 … a Tiger Nel 2004, dopo 3 anni di lavoro e due versioni beta, il JDK 1.5.0

57

J2SE 5: l’evoluzione di JavaLuca Ferrari 113/188

Utilizzo di una annotazionepublic class Test {

@Check(versione=1, stabile=true,nota="Tutto ok!", ultimo_autore="Luca Ferrari")

public void metodo1(){...}

@Check(versione=1, stabile=false,nota="Array index out of bounds!",ultimo_autore="Luca Ferrari")

public void metodo2(){...}

@Check(versione=1, stabile=false,nota="Tutto ok!",ultimo_autore="Giacomo Cabri")

public void metodo3(){...}}

J2SE 5: l’evoluzione di JavaLuca Ferrari 114/188

E adesso?Fino a questo punto abbiamo definito una annotazione e l’abbiamo inserita in una normale classe Java.

Utilizzando la classe Test non noteremmo nessuna differenza, occorre scrivere del codice che analizzi le annotazioni.

Esempio: Un analizzatore che indichi quali metodi sono instabili e chi è il colpevole!

Page 58: J2SE 5: l’evoluzione di Java · 2004. 12. 22. · 3 Luca Ferrari J2SE 5: l’evoluzione di Java 5/188 … a Tiger Nel 2004, dopo 3 anni di lavoro e due versioni beta, il JDK 1.5.0

58

J2SE 5: l’evoluzione di JavaLuca Ferrari 115/188

Analizzare le annotazionipublic static void main(String argv[]){// ottengo tutti i metodi di TestMethod metodi[] = Test.class.getMethods();// utilizzo foreachfor(Method m: metodi){

// questo metodo ha almeno un’annotazione?if(m.isAnnotationPresent(Check.class)){

// prelevo tutte le annotazioni del metodoAnnotation annotazioni[] = m.getAnnotations();// so che le annotazioni sono Check!for(Annotation a: annotazioni){

Check c = (Check)a;// è codice instabile?if(c.stabile()==false){System.out.println("ATTENZIONE:”+m.getName());System.out.println(“ultimo autore: “

+c.ultimo_autore());}

}}}}

J2SE 5: l’evoluzione di JavaLuca Ferrari 116/188

Il risultato

Si noti che si usano i dati annotati tramite chiamate a metodi; anche l’annotazione stessa è trattata come un oggetto normale!

Si presti attenzione alle classi usate!

ATTENZIONE: metodo2

ultimo autore: Luca Ferrari

ATTENZIONE: metodo3

ultimo autore: Giacomo Cabri

output di esecuzione

Page 59: J2SE 5: l’evoluzione di Java · 2004. 12. 22. · 3 Luca Ferrari J2SE 5: l’evoluzione di Java 5/188 … a Tiger Nel 2004, dopo 3 anni di lavoro e due versioni beta, il JDK 1.5.0

59

J2SE 5: l’evoluzione di JavaLuca Ferrari 117/188

Tipi di annotazioniLe annotazioni sono suddivisibili in:1. Marker annotation – sono annotazioni

“vuote” (senza variabili);2. Single-value annotation – annotazioni

con un solo campo (tipicamente value);3. Full annotation – annotazioni

complesse (come nell’esempio precedente).

Nel caso di single-value, se il campo è value, il suo nome può essere omesso da un assegnamento:

@myAnnotation(value=“Luca Ferrari”)

@myAnnotation(“Luca Ferrari”)

J2SE 5: l’evoluzione di JavaLuca Ferrari 118/188

Annotazioni baseJ2SE 5 fornisce alcune annotazioni di base (built-in annotations):

1. @Override – utilizzabile solo per i metodi, indica che il metodo in questione sta ridefinendo un metodo della classe base.

2. @Deprecated – utilizzabile solo per i metodi, indica che il metodo annotato non dovrebbe essere più usato.

3. @SuppressWarnings – disabilita i messaggi di warning del compilatore.

4. @Inherited – (meta annotation) forza una annotazione anche nelle sottoclassi della classe cui quest’ultima è applicata.

Page 60: J2SE 5: l’evoluzione di Java · 2004. 12. 22. · 3 Luca Ferrari J2SE 5: l’evoluzione di Java 5/188 … a Tiger Nel 2004, dopo 3 anni di lavoro e due versioni beta, il JDK 1.5.0

60

J2SE 5: l’evoluzione di JavaLuca Ferrari 119/188

Annotazioni base5. @Retention – (meta annotation) indica a quale

istante di vita del codice l’annotazione deve essere applicata. I valori possibili sono:� RetentionPolicy.SOURCE // no JVM e compiler� RetentionPolicy.CLASS // solo compiler� RetentionPolicy.RUNTIME // solo JVM

6. @Target – (meta annotation) indica a quale porzione di codice una annotazione si riferisce. I valori possibili sono:� ElementType.TYPE // class, interface, enum

� ElementType.FIELD // field

� ElementType.METHOD // method� ElementType.PARAMETER // method parameter� ElementType.CONSTRUCTOR // constructor

� ElementType.LOCAL_VARIABLE // anche catch

� ElementType.ANNOTATION_TYPE // meta annotation

� ElementType.PACKAGE // package

J2SE 5: l’evoluzione di JavaLuca Ferrari 120/188

Utilizzo di più annotazioniSi supponga di voler creare un’annotazione che contenga le informazioni sulla persona che gestisce un pezzo di codice.

package seminario_20.annotazioni;

import java.lang.annotation.*;

@Retention(RetentionPolicy.RUNTIME)

@Target(ElementType.METHOD)

public @interface Check2 {

String assegnato_a();

}

Page 61: J2SE 5: l’evoluzione di Java · 2004. 12. 22. · 3 Luca Ferrari J2SE 5: l’evoluzione di Java 5/188 … a Tiger Nel 2004, dopo 3 anni di lavoro e due versioni beta, il JDK 1.5.0

61

J2SE 5: l’evoluzione di JavaLuca Ferrari 121/188

Utilizzo di più annotazionipublic class Test {

@Check(versione=1, stabile=true,nota="Tutto ok!", ultimo_autore="Luca Ferrari")

public void metodo1(){...}

@Check(versione=1, stabile=false,nota="Array index out of bounds!",ultimo_autore="Luca Ferrari")

public void metodo2(){...}

@Check(versione=1, stabile=false,nota="Tutto ok!",ultimo_autore="Giacomo Cabri")

@Check2(assegnato_a = “Luca Ferrari”)public void metodo3(){...}

}

J2SE 5: l’evoluzione di JavaLuca Ferrari 122/188

Method metodi[] = Test.class.getMethods(); // ottengo tutti i metodifor(Method m: metodi){

if(m.isAnnotationPresent(Check.class)){Annotation annotazioni[] = m.getAnnotations();for(Annotation a: annotazioni){

System.out.println("Annotazione "+a);if(a instanceof Check){

Check c = (Check)a;if(c.stabile()==false){

System.out.println("ATTENZIONE: il metodo “+m.getName());

System.out.println("è instabile.");System.out.println("Ultimo autore: “

+c.ultimo_autore());}

}else if(a instanceof Check2){Check2 c2 = (Check2)a;System.out.println("Assegnato a: "+c2.assegnato_a());

}}

}}

Utilizzo di più annotazioni

Page 62: J2SE 5: l’evoluzione di Java · 2004. 12. 22. · 3 Luca Ferrari J2SE 5: l’evoluzione di Java 5/188 … a Tiger Nel 2004, dopo 3 anni di lavoro e due versioni beta, il JDK 1.5.0

62

J2SE 5: l’evoluzione di JavaLuca Ferrari 123/188

Valori di defaultTramite la parola chiave default, è possibile assegnare un valore iniziale ad un campo di una annotazione.

package seminario_20.annotazioni;

import java.lang.annotation.*;

@Retention(RetentionPolicy.RUNTIME)

@Target(ElementType.METHOD)

public @interface Check3{

boolean testato() default false;

}

J2SE 5: l’evoluzione di JavaLuca Ferrari 124/188

Valori di default: esempiopublic class Test {

@Check(versione=1, stabile=true,nota="Tutto ok!", ultimo_autore="Luca Ferrari")

public void metodo1(){...}

@Check(versione=1, stabile=false,nota="Array index out of bounds!",ultimo_autore="Luca Ferrari")

@Check3(testato=“true”)public void metodo2(){...}

@Check(versione=1, stabile=false,nota="Tutto ok!",ultimo_autore="Giacomo Cabri")

@Check2(assegnato_a = “Luca Ferrari”)@Check3()public void metodo3(){...}

}

testato = false

Page 63: J2SE 5: l’evoluzione di Java · 2004. 12. 22. · 3 Luca Ferrari J2SE 5: l’evoluzione di Java 5/188 … a Tiger Nel 2004, dopo 3 anni di lavoro e due versioni beta, il JDK 1.5.0

63

J2SE 5: l’evoluzione di JavaLuca Ferrari 125/188

Valori di default: esempiopublic static void main(String argv[]){

Test test = new Test();// ottengo tutti i metodi di TestMethod metodi[] = Test.class.getMethods();for(Method m: metodi){if(m.isAnnotationPresent(Check3.class)){

Annotation annotazioni[] = m.getAnnotations();for(Annotation a: annotazioni){

if(a instanceof Check3){Check3 c = (Check3) a;if(c.testato()==false){System.out.println("Metodo non testato! “

+m.getName());}

}}

}}

}

Metodo non testato! metodo3

output di esecuzione

J2SE 5: l’evoluzione di JavaLuca Ferrari 126/188

Gli IDE non annotano (ancora)Gli IDE (ad es. Netbeans, Eclipse) hanno ancora qualche problema/bug nell’uso delle annotazioni. Ad esempio, il code inspector non funziona, vengono segnalati errori (a tempo di digitazione) inesistenti, ecc.

Page 64: J2SE 5: l’evoluzione di Java · 2004. 12. 22. · 3 Luca Ferrari J2SE 5: l’evoluzione di Java 5/188 … a Tiger Nel 2004, dopo 3 anni di lavoro e due versioni beta, il JDK 1.5.0

64

J2SE 5: l’evoluzione di JavaLuca Ferrari 127/188

Tipi di ritorno variabili

J2SE 5: l’evoluzione di JavaLuca Ferrari 128/188

Method Override & Return TypeIn generale non è possibile ridefinire un metodo se la nuova definizione varia il tipo del valore di ritorno.

J2SE 5, sotto opportune condizioni, consente di ridefinire un metodo variandone il tipo di ritorno, ma quest’ultimo deve essere una sottoclasse di quello dell’implementazione originale!

Page 65: J2SE 5: l’evoluzione di Java · 2004. 12. 22. · 3 Luca Ferrari J2SE 5: l’evoluzione di Java 5/188 … a Tiger Nel 2004, dopo 3 anni di lavoro e due versioni beta, il JDK 1.5.0

65

J2SE 5: l’evoluzione di JavaLuca Ferrari 129/188

EsempioSupponendo di avere la seguente gerarchia di tipi di ritorno:

Veicolo

Automobile

package seminario_20.ret;

public class Veicolo {

protected String marca;

protected int cilindrata;

public Veicolo(String marca,

int cilindrata){

this.marca = marca;

this.cilindrata = cilindrata;

}

public String toString(){

return "Veicolo: "+marca+" (“

+cilindrata+")";

}

}

package seminario_20.ret;

public class Automobile

extends Veicolo{

public Automobile(String marca,

int cilindrata){

super(marca,cilindrata);

}

public String toString(){

return "Automobile:"+marca

+" ("+cilindrata+")";

}

}

J2SE 5: l’evoluzione di JavaLuca Ferrari 130/188

EsempioPossono essere definite le seguenti classi:

FabbricaVeicoli

FabbricaAutomobili

package seminario_20.ret;

public class FabbricaVeicoli {

// un metodo che crea un Veicolo

public Veicolo getVeicolo(String marca,

int cilindrata){

return new Veicolo(marca, cilindrata);

}

}

Page 66: J2SE 5: l’evoluzione di Java · 2004. 12. 22. · 3 Luca Ferrari J2SE 5: l’evoluzione di Java 5/188 … a Tiger Nel 2004, dopo 3 anni di lavoro e due versioni beta, il JDK 1.5.0

66

J2SE 5: l’evoluzione di JavaLuca Ferrari 131/188

EsempioPossono essere definite le seguenti classi:

FabbricaVeicoli

FabbricaAutomobili

package seminario_20.ret;

public class FabbricaAutomobili extends FabbricaVeicoli{

// costruisce una Automobile

public Automobile getVeicolo(String marca,

int cilindrata){

return new Automobile(marca, cilindrata);

}

}

J2SE 5: l’evoluzione di JavaLuca Ferrari 132/188

Con JDK < 1.5

Page 67: J2SE 5: l’evoluzione di Java · 2004. 12. 22. · 3 Luca Ferrari J2SE 5: l’evoluzione di Java 5/188 … a Tiger Nel 2004, dopo 3 anni di lavoro e due versioni beta, il JDK 1.5.0

67

J2SE 5: l’evoluzione di JavaLuca Ferrari 133/188

Con JDK 1.5package seminario_20.ret;public class Main {

public static void main(String argv[]){// creo le frabbricheFabbricaVeicoli fv = new FabbricaVeicoli();FabbricaAutomobili fa = new FabbricaAutomobili();

//....Veicolo v = fv.getVeicolo("FIAT",500);Automobile a = fa.getVeicolo("BMW",2500);

System.out.println("Veicolo "+v);System.out.println("Automobile "+a);

}} Veicolo Veicolo: FIAT (500)

Automobile Automobile:BMW (2500)

output di esecuzione

J2SE 5: l’evoluzione di JavaLuca Ferrari 134/188

ArgomentiStoria

(da OAK a J2SE 5)

Novità sintattiche

(boxing, foreach, varargs, static import, enum, output formattato)

Novità semantiche

(generics, annotazioni, tipo di ritorno variabili)

Classi aggiunte o modificate

(Swing, StackTraceElement, InetAdress, Management Factory, …)

Varie

(Pack200, Ergonomics, …)

Risorse

Page 68: J2SE 5: l’evoluzione di Java · 2004. 12. 22. · 3 Luca Ferrari J2SE 5: l’evoluzione di Java 5/188 … a Tiger Nel 2004, dopo 3 anni di lavoro e due versioni beta, il JDK 1.5.0

68

J2SE 5: l’evoluzione di JavaLuca Ferrari 135/188

Swing

J2SE 5: l’evoluzione di JavaLuca Ferrari 136/188

Desktop ClientE’ ora disponibile un nuovo tema di default per Swing: Ocean.

I Look&Feel per Windows e Linux(GTK) sono stati migliorati.

Sono inoltre disponibili le opzioni per il supporto OpenGL:

sun.java2d.opengl=true

e per usare l’implementazione veloce di X11 (XAWT):

awt.toolkit=sun.awt.motif.MToolkit

Page 69: J2SE 5: l’evoluzione di Java · 2004. 12. 22. · 3 Luca Ferrari J2SE 5: l’evoluzione di Java 5/188 … a Tiger Nel 2004, dopo 3 anni di lavoro e due versioni beta, il JDK 1.5.0

69

J2SE 5: l’evoluzione di JavaLuca Ferrari 137/188

Swing e il contentpaneLa libreria Swing definisce i container di primo livello (ad es. JFrame, JDialog) come composizione di una serie di pannelli, il più importante dei quali è il pannello dei contenuti (content pane).

L’aggiunta di componenti grafici (ad es. pulsanti) deve avvenire sul pannello dei contenuti:

this.getContentPane().add(new JButton(“pulsante”);

J2SE 5: l’evoluzione di JavaLuca Ferrari 138/188

getContentPane().add(..) == add(..)Fino ad ora l’utilizzo diretto del metodo add(..)per un frame di primo livello provocava una eccezione.

Ora è possibile richiamare add(..) direttamente per tutti i componenti Swing.

In effetti add(..) ora produce una chiamata a getContentPane().add(..), e quindi le seguenti righe di codice sono equivalenti:

this.getContentPane().add(new JButton(“ciao”));this.add(new JButton(“ciao”));

ma la seconda è più corta e leggibile!

Page 70: J2SE 5: l’evoluzione di Java · 2004. 12. 22. · 3 Luca Ferrari J2SE 5: l’evoluzione di Java 5/188 … a Tiger Nel 2004, dopo 3 anni di lavoro e due versioni beta, il JDK 1.5.0

70

J2SE 5: l’evoluzione di JavaLuca Ferrari 139/188

Agire sul pannello giustoIn maniera simile a quanto avviene per add(..), anche altri metodi la cui chiamata diretta produceva eccezioni sono stati reimplementatiper lavorare direttamente sul pannello dei contenuti (ad es. setLayout(..), remove(..),removeAll(), ecc.).

Occorre comunque tenere presente la struttura stratificata di Swing per non lavorare sul pannello sbagliato!

J2SE 5: l’evoluzione di JavaLuca Ferrari 140/188

Classi Modificate

Page 71: J2SE 5: l’evoluzione di Java · 2004. 12. 22. · 3 Luca Ferrari J2SE 5: l’evoluzione di Java 5/188 … a Tiger Nel 2004, dopo 3 anni di lavoro e due versioni beta, il JDK 1.5.0

71

J2SE 5: l’evoluzione di JavaLuca Ferrari 141/188

Math & StrictMathLa libreria matematica di Java comprende 10 nuovi metodi per il calcolo trigonometrico.

I metodi sono stati aggiunti nelle classi Math e StrictMath.

Si ricordi che molto spesso Mathsi comporta solo da front-end

per StrictMath.

J2SE 5: l’evoluzione di JavaLuca Ferrari 142/188

StackTraceElementIl dump dello stack non è particolarmente utile se non si dispone di una console o di un metodo di cattura dell’output, da qui la necessità di introdurre la possibilità di analisi dello stack.Il package java.lang include ora una classe per un’analisi degli elementi presenti sullo stack di un Thread: StackTraceElement.

La classe Thread è stata modificata di conseguenza, incorporando metodi appositi per ottenere gli elementi presenti nello stack.

Page 72: J2SE 5: l’evoluzione di Java · 2004. 12. 22. · 3 Luca Ferrari J2SE 5: l’evoluzione di Java 5/188 … a Tiger Nel 2004, dopo 3 anni di lavoro e due versioni beta, il JDK 1.5.0

72

J2SE 5: l’evoluzione di JavaLuca Ferrari 143/188

StackTraceElement: un primo esempiopublic class stack{

protected void metodo1(){metodo2();

}

protected void metodo2(){metodo3();

}

protected void metodo3(){analizza_stack();

}

J2SE 5: l’evoluzione di JavaLuca Ferrari 144/188

StackTraceElement: un primo esempioprotected void analizza_stack(){

// ottengo il thread correnteThread mySelf = Thread.currentThread();// ottengo le info sui frame dello stackStackTraceElement frames[] =

mySelf.getStackTrace();// stampo informazioni sullo stackfor(int i=0;i<frames.length;i++){System.out.println("\n\t--- Frame n. "+i+

" ---\n");System.out.println("Metodo: "+

frames[i].getMethodName());System.out.println("File: "+

frames[i].getFileName());System.out.println("Classe/linea: "+

frames[i].getClassName()+"/"+frames[i].getLineNumber());

System.out.println("E' nativo: "+frames[i].isNativeMethod());

}}

Page 73: J2SE 5: l’evoluzione di Java · 2004. 12. 22. · 3 Luca Ferrari J2SE 5: l’evoluzione di Java 5/188 … a Tiger Nel 2004, dopo 3 anni di lavoro e due versioni beta, il JDK 1.5.0

73

J2SE 5: l’evoluzione di JavaLuca Ferrari 145/188

StackTraceElement: un primo esempiopublic static void main(String argv[]){stack test = new stack();test.metodo1();

}}// fine della classe

--- Frame n. 0 ---

Metodo: dumpThreads

File: Thread.java

Classe/linea: java.lang.Thread/-2

E' nativo: true

--- Frame n. 1 ---

Metodo: getStackTrace

File: Thread.java

Classe/linea: java.lang.Thread/1383

E' nativo: false

--- Frame n. 2 ---

Metodo: analizza_stack

File: stack.java

Classe/linea: stack/19

E' nativo: false

...

output di esecuzione

ATTENZIONE: si ricordi che al momento della cattura, sullo stack

sono sempre presenti i metodi getStackTrace e

dumpThreads.

J2SE 5: l’evoluzione di JavaLuca Ferrari 146/188

StackTraceElement: bloccare le chiamate in base allo stack

public class ThreadStack {

protected void metodo1(){metodo2();

}

protected void metodo3(){metodo2();

}

Page 74: J2SE 5: l’evoluzione di Java · 2004. 12. 22. · 3 Luca Ferrari J2SE 5: l’evoluzione di Java 5/188 … a Tiger Nel 2004, dopo 3 anni di lavoro e due versioni beta, il JDK 1.5.0

74

J2SE 5: l’evoluzione di JavaLuca Ferrari 147/188

StackTraceElement: bloccare le chiamate in base allo stack

protected void metodo2(){// ottengo lo stack correnteStackTraceElement[] stack =

Thread.currentThread().getStackTrace();

for(StackTraceElement e:stack){if(e.getMethodName().equals("metodo3")){System.out.println("\tNon puoi invocare questo

metodo");System.out.println("\tcon metodo3 nello stack!");return;

}}

System.out.println("Invocazione riuscita");}

J2SE 5: l’evoluzione di JavaLuca Ferrari 148/188

StackTraceElement: bloccare le chiamate in base allo stack

public static void main(String argv[]){ThreadStack ts = new ThreadStack();ts.metodo1();ts.metodo2();ts.metodo3();

}} // fine della classe

Invocazione riuscita

Invocazione riuscita

Non puoi invocare questo metodo

con metodo3 nello stack!

output di esecuzione

Page 75: J2SE 5: l’evoluzione di Java · 2004. 12. 22. · 3 Luca Ferrari J2SE 5: l’evoluzione di Java 5/188 … a Tiger Nel 2004, dopo 3 anni di lavoro e due versioni beta, il JDK 1.5.0

75

J2SE 5: l’evoluzione di JavaLuca Ferrari 149/188

Thread#getStackTraceOccorre tenere presente che:� quando viene invocato, il metodo getStackTrace() si trova sullo stack, e quindi figura sempre fra i frame più recenti (alti). Inoltre, viene usato un servizio di Thread, dumpThreads(..), che figura anch’esso nello stack(come elemento più recente);� il metodo potrebbe non essere portabile:“Some virtual machines may, under some circumstances, omitone or more stack frames from the stack trace. In the extremecase, a virtual machine that has no stack trace informationconcerning this thread is permitted to return a zero-lengtharray from this method.”

J2SE 5: l’evoluzione di JavaLuca Ferrari 150/188

URLConnectionLa classe URLConnection presenta ora dei metodi per la gestione del connection-timeout relativamente ad ogni istanza.

public int getConnectTimeout()

public void setConnectTimeout(int timeout)

public void setReadTimeout(int timeout)

public int getReadTimeout()

Nelle versioni precedenti, il tempo di timeout era impostabile tramite una proprietà globale (ossia comune a tutte le istanze).

Page 76: J2SE 5: l’evoluzione di Java · 2004. 12. 22. · 3 Luca Ferrari J2SE 5: l’evoluzione di Java 5/188 … a Tiger Nel 2004, dopo 3 anni di lavoro e due versioni beta, il JDK 1.5.0

76

J2SE 5: l’evoluzione di JavaLuca Ferrari 151/188

InetAddressE’ ora possibile testare la raggiungibilità di un host:

public boolean isReachable(int timeout)

throws IOException

Le implementazioni comuni usano pacchetti ICMP ECHO REQUEST, analogamente a quanto fatto dal comando ping.

J2SE 5: l’evoluzione di JavaLuca Ferrari 152/188

Classi aggiunte

Page 77: J2SE 5: l’evoluzione di Java · 2004. 12. 22. · 3 Luca Ferrari J2SE 5: l’evoluzione di Java 5/188 … a Tiger Nel 2004, dopo 3 anni di lavoro e due versioni beta, il JDK 1.5.0

77

J2SE 5: l’evoluzione di JavaLuca Ferrari 153/188

ManagementFactoryE’ stato aggiunto il package java.lang.management per offrire accesso ai dati di esecuzione della JVM; la classe più importante del package è ManagementFactory.

ManagementFactory offre metodi (statici) di accesso a MXBean, oggetti che possono fornire informazioni sullo stato della memoria, dei class loader, ecc. della JVM.

J2SE 5: l’evoluzione di JavaLuca Ferrari 154/188

ManagementFactory: esempiopublic static void main(String argv[]){

// informazioni di loadingClassLoadingMXBean loading =

ManagementFactory.getClassLoadingMXBean();System.out.println("Classi caricate “

+loading.getTotalLoadedClassCount());System.out.println("Classi scaricate “

+loading.getUnloadedClassCount());

// informazioni di memoriaMemoryMXBean mem =

ManagementFactory.getMemoryMXBean();System.out.println("Heap "+mem.getHeapMemoryUsage());System.out.println("Non heap “

+mem.getNonHeapMemoryUsage());System.out.println("Oggetti da finalizzare “

+mem.getObjectPendingFinalizationCount());}

Page 78: J2SE 5: l’evoluzione di Java · 2004. 12. 22. · 3 Luca Ferrari J2SE 5: l’evoluzione di Java 5/188 … a Tiger Nel 2004, dopo 3 anni di lavoro e due versioni beta, il JDK 1.5.0

78

J2SE 5: l’evoluzione di JavaLuca Ferrari 155/188

ManagementFactory: esempio

Classi caricate 296

Classi scaricate 0

Heap init = 0(0K) used = 153712(150K) committed =2031616(1984K) max = 66650112(65088K)

Non heap init = 29556736(28864K) used =12021096(11739K) committed = 29851648(29152K) max =121634816(118784K)

Oggetti da finalizzare 0

output di esecuzione

J2SE 5: l’evoluzione di JavaLuca Ferrari 156/188

FormatterLa classe Formatter consente di applicare una formattazione (specificata tramite una stringa di formato) su una stringa costruita al volo.

Da un punto di vista logico, la classe Formatter svolge il compito della famiglia di funzioni sprintf(..) del C++.

Page 79: J2SE 5: l’evoluzione di Java · 2004. 12. 22. · 3 Luca Ferrari J2SE 5: l’evoluzione di Java 5/188 … a Tiger Nel 2004, dopo 3 anni di lavoro e due versioni beta, il JDK 1.5.0

79

J2SE 5: l’evoluzione di JavaLuca Ferrari 157/188

Formatter: un esempioimport java.util.Formatter;

public class Main {public static void main(String[] args){

StringBuilder result = new StringBuilder();Formatter f = new Formatter(result);f.format("%d - %s",10,"CIAO CIAO");System.out.println(result);

}}

10 – CIAO CIAO

output di esecuzione

J2SE 5: l’evoluzione di JavaLuca Ferrari 158/188

ScannerLa classe java.util.Scanner consente di prelevare con precisione l’input. Svolge la stessa funzione semantica di una scanf(..) del C.

Scanner consente di ricercare espressioni regolari nell’input di riga, di trattare i valori di input come numerici, ecc.

Se il tipo fornito in ingresso non è quello che Scanner si aspetta,

verrà sollevata una eccezione. Ad esempio, se Scanner si aspetta un int

e viene fornita una stringa, Scanner avvertirà dell’errore con una eccezione.

Page 80: J2SE 5: l’evoluzione di Java · 2004. 12. 22. · 3 Luca Ferrari J2SE 5: l’evoluzione di Java 5/188 … a Tiger Nel 2004, dopo 3 anni di lavoro e due versioni beta, il JDK 1.5.0

80

J2SE 5: l’evoluzione di JavaLuca Ferrari 159/188

Scanner: esempioimport java.util.Scanner;

public class scanner{public static void main(String argv[]){

// associo lo scanner a STDINScanner scan = new Scanner(System.in);// leggo tre interi e ne stampo la sommaint uno = scan.nextInt();int due = scan.nextInt();int tre = scan.nextInt();// continua a leggere (senza far nulla) fino// a che l’utente non digita FINITOscan.findInLine("FINITO");scan.close();System.out.println("La somma vale “

+(uno+due+tre));}

}

J2SE 5: l’evoluzione di JavaLuca Ferrari 160/188

Scanner: esempioluca@linux:~/tmp/j1.5/seminario_20> java seminario_20.scanner

10

20

30

La somma vale 60

CIAO

ProVA

FINITO

luca@linux:~/tmp/j1.5/seminario_20>

Page 81: J2SE 5: l’evoluzione di Java · 2004. 12. 22. · 3 Luca Ferrari J2SE 5: l’evoluzione di Java 5/188 … a Tiger Nel 2004, dopo 3 anni di lavoro e due versioni beta, il JDK 1.5.0

81

J2SE 5: l’evoluzione di JavaLuca Ferrari 161/188

java.util.concurrent

E’ disponibile un nuovo package che fornisce classi di utilità generale per applicazioni concorrenti (lock, mutex, semafori, scheduler, ecc.).

Lo scopo di questo package è di semplificare la sincronizzazione dei processi (thread) senza usare le classiche wait()/notify(), che possono portare facilmente a situazioni di stallo.

J2SE 5: l’evoluzione di JavaLuca Ferrari 162/188

java.lang.instrument

Il nuovo package java.lang.instrumentcontiene un (ridotto) set di classi per tecniche di instrumenting (JVMTI).

Instrumenting (dirigere) significa aggiungere ad un metodo del codice di controllo (ad es. prologo o epilogo) per controllarne l’esecuzione.

Simile all’Aspect Oriented Programming e alle tecniche di bytecode manipulation

Page 82: J2SE 5: l’evoluzione di Java · 2004. 12. 22. · 3 Luca Ferrari J2SE 5: l’evoluzione di Java 5/188 … a Tiger Nel 2004, dopo 3 anni di lavoro e due versioni beta, il JDK 1.5.0

82

J2SE 5: l’evoluzione di JavaLuca Ferrari 163/188

JVMTIOltre a fornire supporto per l’instrumentdi codice Java, JVMTI fornisce un’implementazione dell’utility HPROF (Heap/CPU Profiling tool).

HPROF è una libreria che consente di monitorare l’esecuzione del codice Java, fornendo informazioni sull’uso delle risorse.

J2SE 5: l’evoluzione di JavaLuca Ferrari 164/188

ArgomentiStoria

(da OAK a J2SE 5)

Novità sintattiche

(boxing, foreach, varargs, static import, enum, output formattato)

Novità semantiche

(generics, annotazioni, tipo di ritorno variabili)

Classi aggiunte o modificate

(Swing, StackTraceElement, InetAdress, Management Factory, …)

Varie

(Pack200, Ergonomics, …)

Risorse

Page 83: J2SE 5: l’evoluzione di Java · 2004. 12. 22. · 3 Luca Ferrari J2SE 5: l’evoluzione di Java 5/188 … a Tiger Nel 2004, dopo 3 anni di lavoro e due versioni beta, il JDK 1.5.0

83

J2SE 5: l’evoluzione di JavaLuca Ferrari 165/188

Ergonomics & performance

J2SE 5: l’evoluzione di JavaLuca Ferrari 166/188

ErgonomicsLa JVM include ora una serie di opzioni per il tuning e il profiling delle applicazioni.

Le opzioni di ergonomics coprono la scelta del garbage collector, l’utilizzo del nuovo sistema di class-sharing, dimensione dell’heap e degli spazi generazionali, ecc.

Page 84: J2SE 5: l’evoluzione di Java · 2004. 12. 22. · 3 Luca Ferrari J2SE 5: l’evoluzione di Java 5/188 … a Tiger Nel 2004, dopo 3 anni di lavoro e due versioni beta, il JDK 1.5.0

84

J2SE 5: l’evoluzione di JavaLuca Ferrari 167/188

La scelta del garbage collectorSono disponibili le seguenti opzioni:� -Xnoclassgc disabilita la class garbagecollection;� -Xincgc (mark & sweep) abilita il garbage collector incrementale;� -XX:+UseParallelGC abilita il GC generazionale parallelo (throughputcollector);� -XX:+UseConcMarkSweepGC versione parallela di –Xincgc.

J2SE 5: l’evoluzione di JavaLuca Ferrari 168/188

Il garbage collector in azioneUsando il flag –verbose:gc è possibile osservare il garbage collector in azione:

Dimensione oggetti prima del passaggio del GC.

Dimensione oggetti dopo il passaggio del GC.

Spazio disponibile in

totale.

Tempo di esecuzione del GC.

Page 85: J2SE 5: l’evoluzione di Java · 2004. 12. 22. · 3 Luca Ferrari J2SE 5: l’evoluzione di Java 5/188 … a Tiger Nel 2004, dopo 3 anni di lavoro e due versioni beta, il JDK 1.5.0

85

J2SE 5: l’evoluzione di JavaLuca Ferrari 169/188

La dimensione della memoriaE’ possibile un controllo accurato sulla dimensione della memoria heap:� -Xms imposta la dimensione iniziale dell’heap;� -Xmx imposta la dimensione massima dell’heap;� -Xss imposta la dimensione dello stack di un thread;� -XXMinHeapFreeRatio, -XXMaxHeapFreeRatioimpostano il limite inferiore/superiore (percentuale) dell’heap libero per forzare un passagio del GC. Le generazioni possono essere ridimensionate. Per un architettura a 32 bit i valori sono rispettivamente 40% e 70%.

J2SE 5: l’evoluzione di JavaLuca Ferrari 170/188

Un esempio casalingopublic class runner{

public static void main(String argv[]){long start,stop;start = System.currentTimeMillis();for(int i=0;i<10000;i++){

for(int j=0;j<10000;j++){String s = new String("Una stringa

abbastanza lunga!!!!!!");}

JFrame f = new JFrame("Nuovo frame");}

stop = System.currentTimeMillis();System.out.println("Tempo di esecuzione “

+(stop-start)+" ms");}

}

Page 86: J2SE 5: l’evoluzione di Java · 2004. 12. 22. · 3 Luca Ferrari J2SE 5: l’evoluzione di Java 5/188 … a Tiger Nel 2004, dopo 3 anni di lavoro e due versioni beta, il JDK 1.5.0

86

J2SE 5: l’evoluzione di JavaLuca Ferrari 171/188

Un esempio casalingo

8682 ms-Xms 64000000 –XX:MinHeapFreeRatio=1

-XX:MaxHeapFreeRatio=99

8843 ms-Xms 64000000 –XX:MinHeapFreeRatio=1

9033 ms-Xms 64000000

47218 ms-int

9584 ms-incgc

12478 ms-noclassgc

12518 msnormale

J2SE 5: l’evoluzione di JavaLuca Ferrari 172/188

Shared Class DataE’ ora possibile creare al volo degli archivi di classi da condividere fra più JVM (Shared Class Data).

Il flag per controllare il meccanismo delle classi condivise è –Xshare:{auto|off|on}

Page 87: J2SE 5: l’evoluzione di Java · 2004. 12. 22. · 3 Luca Ferrari J2SE 5: l’evoluzione di Java 5/188 … a Tiger Nel 2004, dopo 3 anni di lavoro e due versioni beta, il JDK 1.5.0

87

J2SE 5: l’evoluzione di JavaLuca Ferrari 173/188

Prestazioni del nuovo JDK

J2SE 5: l’evoluzione di JavaLuca Ferrari 174/188

Prestazioni del nuovo JDK

Page 88: J2SE 5: l’evoluzione di Java · 2004. 12. 22. · 3 Luca Ferrari J2SE 5: l’evoluzione di Java 5/188 … a Tiger Nel 2004, dopo 3 anni di lavoro e due versioni beta, il JDK 1.5.0

88

J2SE 5: l’evoluzione di JavaLuca Ferrari 175/188

Pack200, lint

J2SE 5: l’evoluzione di JavaLuca Ferrari 176/188

Pack200Una nuova tecnica di compressione degli archivi jar (già compressi – zip).

Fornisce ad applicazioni e applet un meccanismo per ridurre la banda richiesta al trasferimento di un insieme di classi.

Può essere combinata con gzip per offrire maggiore compressione.

Non sostituisce gli archivi jar!!

Page 89: J2SE 5: l’evoluzione di Java · 2004. 12. 22. · 3 Luca Ferrari J2SE 5: l’evoluzione di Java 5/188 … a Tiger Nel 2004, dopo 3 anni di lavoro e due versioni beta, il JDK 1.5.0

89

J2SE 5: l’evoluzione di JavaLuca Ferrari 177/188

Pack200Dalla versione 1.1 del protocollo HTTP (RFC 2616), è possibile inviare archivi jar in forma compressa.

Le tecniche supportate (da HTTP) sono: gzip, compress, deflate.

Pack200 si appoggia a gzip.

Ogni server dovrebbe conservare tre copie dello stesso jar: normale (.jar), compresso gzip(.jar.gz), compresso gzip+pack200 (.jar.pack.gz).

J2SE 5: l’evoluzione di JavaLuca Ferrari 178/188

Pack200: funzionamento su HTTP

AE = Accepted Encoding

CE = Content Encoding

CT = Content Type

Page 90: J2SE 5: l’evoluzione di Java · 2004. 12. 22. · 3 Luca Ferrari J2SE 5: l’evoluzione di Java 5/188 … a Tiger Nel 2004, dopo 3 anni di lavoro e due versioni beta, il JDK 1.5.0

90

J2SE 5: l’evoluzione di JavaLuca Ferrari 179/188

Pack200: funzionamento su HTTP

AE = Accepted Encoding

CE = Content Encoding

CT = Content Type

J2SE 5: l’evoluzione di JavaLuca Ferrari 180/188

Pack200: funzionamento su HTTP

AE = Accepted Encoding

CE = Content Encoding

CT = Content Type

Page 91: J2SE 5: l’evoluzione di Java · 2004. 12. 22. · 3 Luca Ferrari J2SE 5: l’evoluzione di Java 5/188 … a Tiger Nel 2004, dopo 3 anni di lavoro e due versioni beta, il JDK 1.5.0

91

J2SE 5: l’evoluzione di JavaLuca Ferrari 181/188

Pack200: funzionamento su HTTP

AE = Accepted Encoding

CE = Content Encoding

CT = Content Type

J2SE 5: l’evoluzione di JavaLuca Ferrari 182/188

UtilizzoI livelli di compressione dei vari tool sono i seguenti:jar: circa il 3%gzip: circa il 14%pack200: fino al 50% (dichiarati al 90%!)

Da riga di comando è sufficiente utilizzare l’utility pack200/unpack200. Ad esempio:

pack200 –repack myJar.jar

Page 92: J2SE 5: l’evoluzione di Java · 2004. 12. 22. · 3 Luca Ferrari J2SE 5: l’evoluzione di Java 5/188 … a Tiger Nel 2004, dopo 3 anni di lavoro e due versioni beta, il JDK 1.5.0

92

J2SE 5: l’evoluzione di JavaLuca Ferrari 183/188

FunzionamentoIl funzionamento si basa sui seguenti

passi:1. vengono fusi (e ordinati) i constant-

pool delle classi contenute nell’archivio jar;

2. vengono rimossi gli attributi ridondanti delle classi;

3. viene usata una tecnica di codifica a lunghezza variabile.

J2SE 5: l’evoluzione di JavaLuca Ferrari 184/188

lintIl compilatore ingloba ora un programma, simile a lint per C, che si occupa di verificare la correttezza del codice (ad es. case senza break, uso di metodi deprecated, ecc.).Per attivare lint è sufficiente fornire l’opzione –Xlint al compilatore javac, con uno dei seguenti completamenti:� -Xlint:none – disabilita tutti i warning, se non marcati come obbligatori nel Java Language Specification� -Xlint:unchecked – fornisce dettagli per le conversioni di tipo� -Xlint:path – avvisa nel caso si usino percorsi inesistenti per classpath, sourcepath, ecc.� -Xlint:finally – avvisa per clausole finally che possono produrre problemi

Page 93: J2SE 5: l’evoluzione di Java · 2004. 12. 22. · 3 Luca Ferrari J2SE 5: l’evoluzione di Java 5/188 … a Tiger Nel 2004, dopo 3 anni di lavoro e due versioni beta, il JDK 1.5.0

93

J2SE 5: l’evoluzione di JavaLuca Ferrari 185/188

ArgomentiStoria

(da OAK a J2SE 5)

Novità sintattiche

(boxing, foreach, varargs, static import, enum, output formattato)

Novità semantiche

(generics, annotazioni, tipo di ritorno variabili)

Classi aggiunte o modificate

(Swing, StackTraceElement, InetAdress, Management Factory, …)

Varie

(Pack200, Ergonomics, …)

Risorse

J2SE 5: l’evoluzione di JavaLuca Ferrari 186/188

Risorse

Page 94: J2SE 5: l’evoluzione di Java · 2004. 12. 22. · 3 Luca Ferrari J2SE 5: l’evoluzione di Java 5/188 … a Tiger Nel 2004, dopo 3 anni di lavoro e due versioni beta, il JDK 1.5.0

94

J2SE 5: l’evoluzione di JavaLuca Ferrari 187/188

Risorse

URL� http://www.java.net� http://java.sun.com/� http://www.java.net� http://www.mokabyte.it� http://www.gamelan.com� http://polaris.ing.unimo.it/fiC/laboratorio.

html

J2SE 5: l’evoluzione di JavaLuca Ferrari 188/188

Riflessione conclusiva

Your development cycle is muchfaster because Java is interpreted. The compile-link-load-test-crash-

debug cycle is obsolete.

(James Gosling)