JAVA in ACTION - Dipartimento di Ingegneria dell`Informazione

JAVA in ACTION
Jacopo Torrini
Dipartimento di Ingegneria dell'Informazione
Laboratorio di Tecnologie del Software
[email protected]
Installazione Java
●
●
Su Windows, dal sito Oracle installare l'ultima
versione della JDK (7)
Su ubuntu aggiungere i repo webupd8team
sudo add-apt-repository ppa:webupd8team/java
sudo apt-get install oracle-jdk7-installer
oppure installare il .run per linux dal sito Oracle
Hello World
●
Creare un file HelloWorldApp.java
class HelloWorldApp {
public static void main(String[] args) {
System.out.println("Hello World!");
}
}
Compilare ed eseguire
●
Da riga di comando:
javac HelloWorldApp.java
java HelloWorldApp
Package
●
Permette di definire un namespace per un set
di classi tra loro correlate
●
●
●
Permette di organizzare meglio il codice tramite
una struttura gerarchica di cartelle
Permette di avere classi differenti con lo stesso
nome dentro package diversi. Risolve soprattutto
conflitti di nome su librerie differenti.
Permette di definire un accesso limitato a metodi o
attributi di una classe alle sole classi dello stesso
package
Struttura dei package
●
●
●
Il package deve contenere uno o più classi o
interfacce, ossia non può essere vuoto.
Le classi o interfacce che sono in un package
devono avere i file sorgenti nella stessa
struttura di directory corrispondente al nome del
package.
Il nome del package viene costruito a partire
dal path nel file system del package root (o
default) utilizzando come separatore il “.”
Esempio di package
●
●
Considerando come root
package la cartella src la
classe MyClass appartiene al
package
com.mycompany.myproject
I .class generati dal
compilatore hanno una
struttura del tutto equivalente a
quella dei sorgenti
Nomi delle classi e import
●
●
●
●
Come convenzione, per avere nomi di package univoci, si utilizza
il dominio della propria azienda/organizzazione in ordine inverso
completato con nomi specifici dell'applicazione
( com.mycompany.myproject)
Per riferirsi ad una classe deve essere usato il suo nome
completo, ossia il nome del package in cui risiede la classe più il
nome semplice della classe definito nel .java
(com.mycompany.myproject.MyClass)
Per abbreviare la scrittura del nome della classe è possibile
utilizzare la keyword import:
import com.mycompany.myproject.MyClass
In questo modo è sufficiente usare MyClass nel codice.
In caso di conflitti di nome nello stesso file, una delle due classi
deve essere obbligatoriamente usata col nome completo
Class files
●
●
●
●
●
Quando si compila un programma java vengono generati tanti file
.class quante sono le classi java del programma, incluse le classi
multiple definite in un unico file java, le nested class e le inner class,
anonime e non.
Nel caso di classi java semplici, anche se multiple per file, il nome del
.class è pari al nome della classe
Nel caso di nested o inner class il nome è pari al nome della classe
seguito dal simbolo $ seguito dal nome della classe nested o inner
Nel caso di inner class anonime vale lo stesso discorso delle classi
inner semplici, con la variante che il nome della inner class anonima
viene generato dal compilatore (un numero progressivo)
I .class sono creati all'interno di cartelle che duplicano la struttura
delle cartelle dei file sorgenti
Hello World con package
●
●
●
●
●
Creare la cartella hello nella cartella root
Nella cartella hello creare il file
HelloWorldApp.java come l'esempio
precedente
Aggiungere all'inizio del file lo statement
package hello;
Compilare il file con
javac HelloWorldApp.java
Eseguire l'applicazione dalla cartella root con
java hello.HelloWorldApp
Esecuzione di un programma
●
●
Un programma java è un'insieme di file .class
all'interno di una struttura di cartelle
È sufficiente avere una classe con un metodo
public static void main(String[]args)
NOTA: Possono esserci più classi con un metodo main
●
●
●
Una classe viene caricata dalla virtual machine solo
quando viene utilizzata in un altra classe (lazy load)
Per trovare una classe la VM utilizza il nome del file .class
associato alla classe stessa. Il path del file viene generato
tramite il nome del package associato alla classe.
Se il file viene trovato viene caricato dalla VM, altrimenti
viene sollevata un eccezione.
Classpath
●
●
●
Finora abbiamo supposto l'esistenza di una
sola cartella root.
In realtà in java è possibile creare applicazioni i
cui file .class stanno su differenti strutture di
cartelle (e pure in file compressi). I nomi dei
package sono costruiti rispettivamente a partire
dalla cartella root di ogni struttura.
Ogni cartella root di queste strutture costituisce
un componente del classpath di esecuzione di
un programma java.
Esempio di classpath
Jar
●
●
●
●
Un insieme di file .class con la propria struttura
di cartelle può essere impacchettato all'interno
di un file .jar (che altro non è che uno zip).
Un jar può essere utilizzato come componente
del classpath
In questo caso la cartella root è la root dello zip
e la virtual machine è in grado di caricare i
.class direttamente dal file compresso.
Normalmente le librerie java sono semplici file
.jar
Esecuzione con classpath
java -cp /home/user/src1/;src2/ hello.HelloWorldApp
java -cp lib.jar;src1/ hello.HellWorldApp
API
●
●
Application Programming Interface
La API fornisce le funzionalità principali del linguaggio Java. Offre
un vasto set di classi pronte all'uso per diversi scopi, dagli oggetti
di base fino alle classi di networking o security, per la generazione
di XML e per l'accesso a database. L'API standard è molto ampia.
Object – metodo equals
public boolean equals( Object obj )
●
●
●
Esegue un test di uguaglianza logico, basato sul valore.
Già definito in Object in cui riporta true solo se l'istanza passata è la stessa di quella su cui si invoca il
metodo (obj == this)
Inutile ridefinirlo nei seguenti casi:
●
Ogni istanza della classe è univoca di per sé (Thread)
●
Non mi interessa eseguire un confronto logico (JButton)
●
●
●
Una superclasse lo ha già ridefinito e vale anche per la sottoclasse (AbstractSet, AbstractList, AbstractMap)
NOTA: è sempre meglio evitare di ridefinirlo in più di una sottoclasse (vedere esempio prossime slide)
Quindi si ridefinisce quando per la classe si applica il concetto di logical equality, che vale di solito per value
class, come Integer, String, Date.
Proprietà che deve rispettare:
●
Riflessiva: x.equals(x) is true
●
Symmetric: x.equals(y)==y.equals(x)
●
Transitiva: x.equals(y), y.equals(z) => x.equals(z)
●
Consistenza: x.equals(y) riporta consistentemente true o false se lo stato dell'oggetto non cambia
●
x.equals(null) riporta sempre false
Esempio con equals
public final class PhoneNumber {
private final short areaCode;
private final short exchange;
private final short extension;
public boolean equals(Object o) {
if (o == this)
return true;
if (!(o instanceof PhoneNumber))
return false; //questo include o==null
PhoneNumber pn = (PhoneNumber)o;
return pn.extension == extension && pn.exchange == exchange
&& pn.areaCode == areaCode;
}
}
Esempio equals con ereditarietà
public class Point {
private final int x;
private final int y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
public boolean equals(Object o) {
if (!(o instanceof Point))
return false;
Point p = (Point)o;
return p.x == x && p.y == y;
}
}
public class ColorPoint extends Point {
private Color color;
public ColorPoint(int x, int y, Color color) {
super(x, y);
this.color = color;
}
//Broken - violates symmetry!
public boolean equals(Object o) {
if (!(o instanceof ColorPoint))
return false;
ColorPoint cp = (ColorPoint)o;
return super.equals(o) && cp.color == color;
}
}
Object – metodo hashCode
public int hashCode()
●
Riporta un intero che rappresenta l'hash code dell'oggetto
●
Definito in Object e riporta un valore associato all'istanza dell'oggetto
●
●
Deve essere ridefinito in tutte le classi che ridefiniscono equals in modo da
funzionare bene nelle collezioni basate su hash code (Set, Map)
Valgono le seguenti proprietà:
●
●
●
●
Deve riportare un valore consistente se chiamato più volte sulla stessa istanza.
Se lo stato dell'oggetto non cambia deve riportare sempre lo stesso valore.
Non è necessario che riporti il medesimo valore su esecuzioni differenti del
programma.
Se due istanze sono uguali per valore, ossia x.equals(y) riporta true, allora il
metodo hashCode deve riportare lo stesso intero se invocato sulle due istanze.
Non è necessario che hashCode riporti valori differenti per due istanze che non
sono equals, ma va tenuto conto che produrre valori differenti per istanze non
equals può migliorare la performance delle hash table.
Esempi di hashCode
public int hashCode() {
int result = 17;
result = 37*result + areaCode;
result = 37*result + exchange;
result = 37*result + extension;
return result;
}
//valido ma da non usare!!
public int hashCode() { return 42; }
Altre considerazioni
●
●
Un altro metodo interessante di Object è
public String toString().
Deve essere usato solo a scopi di debug e
deve dare una rappresentazione testuale
dell'oggetto
I metodi equals e hasCode possono essere
generati automaticamente. Le IDE per lo
sviluppo java di solito hanno questa funzionalità
Collections
●
●
A collection — sometimes called a container — is simply an object that groups
multiple elements into a single unit. Collections are used to store, retrieve,
manipulate, and communicate aggregate data. Typically, they represent data items
that form a natural group, such as a poker hand (a collection of cards), a mail folder
(a collection of letters), or a telephone directory (a mapping of names to phone
numbers).
A collections framework is a unified architecture for representing and manipulating
collections. All collections frameworks contain the following:
●
●
●
Interfaces: These are abstract data types that represent collections. Interfaces allow
collections to be manipulated independently of the details of their representation. In
object-oriented languages, interfaces generally form a hierarchy.
Implementations: These are the concrete implementations of the collection interfaces. In
essence, they are reusable data structures.
Algorithms: These are the methods that perform useful computations, such as searching
and sorting, on objects that implement collection interfaces. The algorithms are said to be
polymorphic: that is, the same method can be used on many different implementations of
the appropriate collection interface. In essence, algorithms are reusable functionality.
Java collections - interfaces
Collection interface
The Collection interface contains methods that perform basic operations, such as
●
●
●
int size()
●
boolean isEmpty()
●
boolean contains(Object element)
●
boolean add(E element)
●
boolean remove(Object element)
●
Iterator<E> iterator()
It also contains methods that operate on entire collections, such as
●
boolean containsAll(Collection<?> c)
●
boolean addAll(Collection<? extends E> c)
●
boolean removeAll(Collection<?> c)
●
boolean retainAll(Collection<?> c)
●
void clear().
Additional methods for array operations such as
●
Object[] toArray().
Traversing collections
For-each construct
for (Object o : collection)
System.out.println(o);
●
Iterator: An Iterator is an object that enables you to traverse through a collection
and to remove elements from the collection selectively, if desired. You get an
Iterator for a collection by calling its iterator method. The following is the Iterator
interface.
public interface Iterator<E> {
boolean hasNext();
E next();
void remove(); //optional
}
●
for (Iterator<String> it = c.iterator(); it.hasNext(); ){
String s = it.next();
System.out.println(s);
}
Collection algorithms
●
The polymorphic algorithms are pieces of reusable functionality
provided by the Java platform. All of them come from the Collections
class, and all take the form of static methods whose first argument is
the collection on which the operation is to be performed. The great
majority of the algorithms provided by the Java platform operate on List
instances, but a few of them operate on arbitrary Collection instances.
●
Sorting
●
Shuffling
●
Routine Data Manipulation (reverse, fill, copy, swap, addAll)
●
Searching
●
Composition (frequency, disjoint)
●
Finding Extreme Values (min, max)
Set
●
●
A Set is a Collection that cannot contain duplicate elements. It models
the mathematical set abstraction. The Set interface contains only
methods inherited from Collection and adds the restriction that duplicate
elements are prohibited. Set also adds a stronger contract on the
behavior of the equals and hashCode operations, allowing Set instances
to be compared meaningfully even if their implementation types differ.
Two Set instances are equal if they contain the same elements.
The Java platform contains three general-purpose Set implementations:
HashSet, TreeSet, and LinkedHashSet
Set<String> noDups = new HashSet<String>();
Collection<Integer> other = new TreeSet<Integer>();
List
●
A List is an ordered Collection (sometimes called a sequence). Lists may
contain duplicate elements. In addition to the operations inherited from
Collection, the List interface includes operations for the following:
●
●
●
●
●
Positional access — manipulates elements based on their numerical position in
the list. This includes methods such as get, set, add, addAll, and remove.
Search — searches for a specified object in the list and returns its numerical
position. Search methods include indexOf and lastIndexOf.
Iteration — extends Iterator semantics to take advantage of the list's sequential
nature. The listIterator methods provide this behavior.
Range-view — The sublist method performs arbitrary range operations on the list.
The Java platform contains two general-purpose List implementations.
ArrayList, which is usually the better-performing implementation, and
LinkedList which offers better performance under certain circumstances.
List<Integer> list = new ArrayList<Integer>();
Map
●
●
A Map is an object that maps keys to values. A map cannot contain
duplicate keys: Each key can map to at most one value. It models
the mathematical function abstraction. The Map interface includes
methods for basic operations (such as put, get, remove,
containsKey, containsValue, size, and empty), bulk operations (such
as putAll and clear), and collection views (such as keySet, entrySet,
and values).
The Java platform contains three general-purpose Map
implementations: HashMap, TreeMap, and LinkedHashMap
Map<String, Integer> m = new HashMap<String, Integer>();
m.put(“William”,1955);
m.put(“Steven”, 1955);
m.put(“Linus”, 1969);
IDE
●
●
●
Sviluppare da riga di comando non è il modo
corretto.
Una IDE (Integrated Development
Environment) è necessaria per avere una serie
di funzionalità indispensabili per lo sviluppo del
software.
Esistono varie IDE open source o gratuite:
Eclipse, Net beans, IntelliJ IDEA community
edition...
Eclipse
●
Fornisce una piattaforma aperta per tool di
sviluppo di applicazioni
●
Gira su un vasto range di sistemi operativi
●
Language-neutral
●
HTML, Java, C, JSP, EJB, XML
●
Facilita l’integrazione di tool
Eclipse – gestione codice
●
●
●
Esplorazione dei packages e delle classi con
struttura ad albero
Ricerca veloce della dichiarazione di un
metodo, una classe di una variabile
Informazioni istantanee sugli elementi del
codice
●
tooltip sull’elemento
●
documentazione dell’elemento
●
Ricerca di elementi in più files
●
Caller graph dei metodi
Eclipse – scrittura codice
●
●
Evidenziazione immediata errori di sintassi
Completamento automatico di classi, variabili,
metodi
●
Import automatici
●
Code formatter
●
Code templates
●
Scrittura automatica di main, override di metodi,
setter e getter, costruttori, delegate methods,
equals e hashCode ecc...
Eclipse - rifattorizzazione
●
●
●
Conoscere in anticipo l’impatto di una modifica
sul codice
Possibilità di modificare un elemento
mantenendo la semantica di tutto il codice
Possibilità di decidere quali cambiamenti
effettuare
●
Preview dei cambiamenti
●
Undo e Redo del refactoring
●
Esempi: rename, change method signature,
pull up, pull down...
Eclipse – debug e test
●
Step in, out, over...
●
Breakpoints
●
Conditional breakpoints
●
Variables
●
Watches
●
Stack trace
●
Integrazione con JUnit
Eclipse - installazione
●
Scaricare Eclipse IDE for Java EE Developers dalla
pagina web:
http://www.eclipse.org/downloads/
●
Scompattare in una qualsiasi cartella
●
Aprire tramite il file eseguibile
●
●
Selezionare una cartella come workspace (anche quello di
default)
Sotto Windows – Preferences – Java - Installed JREs
verificare che sia selezionata una JDK (non una JRE). In
caso contrario aggiungerne una e selezionarla dal file
system
Eclipse – creazione progetto java
●
Dal menu File selezionare New – Java Project
●
Seguire il wizard fino in fondo e premere Fine.
●
●
●
Cliccare col destro sulla cartella src nel
Package Explorer e selezionare New – Class
Specificare un nome di package e un nome di
classe e premere Fine
Ogni volta che un file viene salvato, viene
anche
compilato automaticamente
Eclipse – esecuzione
●
●
●
Definire il metodo main in una classe java
Cliccare col destro sul nome del file java nel
Package Explorer
Lanciare il comando Run as – Java application
Eclipse – UI
●
Configurazione dell'interfaccia
●
Perspectives
●
Package explorer
●
Outline
●
Javadoc
●
Breakpoints
Eclipse – multiprogetto e librerie
●
●
Creazione di un altro progetto
Impostazione del primo progetto nel classpath
del secondo
●
●
●
Click col destro sul progetto – properties – java
build path - Projects
Utilizzo di classi del primo progetto nel secondo
progetto
Aggiunta di librerie esterne
●
Click col destro sul progetto - Properties – java
build path - Libraries