Il sistema dei tipi Java - Digilander

Il sistema dei tipi Java
Il sistema di tipi in Java
• Il Type System è l’insieme di regole che un
compilatore utilizza per associare ad ogni
variabile ed espressione calcolata un suo tipo.
Il Type System è utilizzato dal compilatore per
svolgere la fase del “type checking”, il
controllo sui tipi
L3-Linguaggi Progammazione II-unina 2
In Java l’assegnazione dei tipi è “statica”, il type
checking è svolto a compilation time e non a
run time.
In Java non ci sono errori di tipo a run time,
come ad esempio il C (o il C++)
In realtà Java consente anche il controllo dei tipi
a run time (operatore instanceof)
L3-Linguaggi Progammazione II-unina 3
Il Type System in Java
Il sistema dei tipi in Java si basa sui tipi primitivi,
i tipi array e i tipi riferimento
Java è fortemente tipato
• I tipi dei valori non possono essere errati
Java è staticamente tipato
• Gli errori sui tipi vengono rilevati a
compilation time
L3-Linguaggi Progammazione II-unina 4
I tipi Java
• Primitivi-> int, short, long, byte, char, float, double,
boolean.
• null->il tipo del valore nullo
• array ->tipi degli array di valori
• Classe (o riferimento) -> tipi degli oggetti, interfecce,
enumerazioni
Conversioni implicite per i tipi primitivi
byte -> short, short -> int, int -> float,
float -> double, char -> int
Esiste un tipo void?
L3-Linguaggi Progammazione II-unina 5
Regole per l'assegnazione del tipo
alle espressioni
Il Type System fornisce delle regole per
l'assegnazione dei tipi alle espressioni
• x + y : int
se x e y sono di tipo byte, short, char, int
• x + y : long
if x o y sono di tipo byte, short, char, int, long
long e almeno è di tipo long
...
L3-Linguaggi Progammazione II-unina 6
Gli array in Java
• Gli array in java hanno dimensione fissa e
possono essere di qualsiasi tipo
• Un array di valori di tipo T si denota con
l’istruzione T[].
• Un array di dimensione n di tipo T si
costituisce con una espressione new T[n]
• Gli elementi dell’array si accedono attraverso
la notazione a[i] (0<=i<=n-1)
L3-Linguaggi Progammazione II-unina 7
I tipi riferimento
• I tipi riferimento (o semplicemente tipi classe)
sono i tipi degli oggetti e delle interfacce
• Dal punto di vista del type checking, Java
verifica che un oggetto sia di un certo tipo, o
del tipo di una classe che estende
• Per assegnare i tipi agli oggetti Java utilizza
una relazione tra i tipi riferimento, detta
relazione di sottotipo
L3-Linguaggi Progammazione II-unina 8
La relazione di sottotipo
• Si dice che S è un sottotipo di T se si verifica una delle
seguenti condizioni:
(1) S e T sono dello stesso tipo
(2) S e T sono entrambe di tipo classe, e S una sottoclasse
diretta di (o implementa) T, o è una sottoclasse di
sottoclassi di T (sottoclasse indiretta)
(3) S e T sono entrambi di tipo array, S=S’[] T=T’[], e S’ è
un sottotipo di T’
(4) S non è un tipo primitivo e T è di tipo Object
(5) S è il tipo null, e T non è un tipo primitivo
La relazione è riflessiva, antisimmetrica e transitiva: è una
relazione di ordine sui tipi classe
L3-Linguaggi Progammazione II-unina 9
public class Person {
public String nome;
public Person (String n) {
this.nome = n;
}
}
public class Military extends Person {
public void executeOrder (String ordine) {
//== …
}
}
Per la relazione di sottotipo:
Military è sottotipo di Person
Un qualsiasi tipo array T[] è sottotipo di Object
Military[] è un sottotipo di Person[].
L3-Linguaggi Progammazione II-unina 10
Regole di assegnazione tipi
riferimenti
• Un oggetto S non può essere convertito in uno
in cui non è in relazione di sottotipo (Es. Un
auto non può essere convertita in persona)
• Un oggetto O di tipo S può essere convertito
in uno P di tipo T se S è sottotipo di T. La
conversione è implicita.
• Un oggetto può essere convertito nel tipo di
una sottoclasse, ma con il cast esplicito. La
JVM effettua un run time check.
L3-Linguaggi Progammazione II-unina 11
L’operatore “istanceof”
L’operatore instanceof si definisce in termini di
della relazione di sottotipo
A istanceof B <-> true se A non è nullo e il tipo di
A è un sottotipo di T
public class Worker extends Person {
public void faiTurno (String Turno) {
//== …
}
}
L3-Linguaggi Progammazione II-unina 12
Assegnazione dei tipi
La relazione di sottotipo ricorre quando la JVM
deve assegnare i tipi nelle espressioni
Un tipo T è assegnabile ad un tipo U se
• T è sottotipo di U
oppure
• T ed U sono tipi primitivi e c'è una conversione
implicita da T ad U.
L3-Linguaggi Progammazione II-unina 13
• Supponiamo esista una classe che è in
grado di assegnare dei compiti alle persone
public void assignTask(Person p) {
//==…
}
Military m=new Military(“J.Smith”);
assignTask(m);
Poiché Java è staticamente tipato, durante
l’esecuzione del metodo si potranno eseguire solo
i metodi della classe “Person”
L’”upcust“, la conversione implicita da sottotipo a
tipo, è automatica.
L3-Linguaggi Progammazione II-unina 14
• Il downcast è invece la conversione di un tipo
ad un suo sottotipo, e si puo’ realizzare con
l’operatore “instanceof”
ES
public void assignTask (Person l) {
Military m = (Military) l;
m.executeOrder (“FAI LA GUARDIA");
}
Nel caso “l” sia un tipo Worker si ottiene l’ eccezione
ClassCastException
L3-Linguaggi Progammazione II-unina 15
public void assignTask (Person l) {
Military m;
if (l instanceOf Military) {
m = (Military) l;
m.executeOrder(“FAI LA GUARDIA");
}
}
/* es */
L3-Linguaggi Progammazione II-unina 16
I tipi e gli array
• Per la relazione di sottotipo, un array è comunque un
sottotipo di “array di Object”
• La conseguenza è che esiste una grande libertà di
manipolare gli array. Un volta definito un metodo in
grado di operare su array di Object, questo puo’
operare su qualsiasi array.
• In realtà non è possibile cambiare il tipo di oggetti
conservati in una array a run time, la JVM solleva
l’eccezione ArrayStoreException
Object x[] = new String[3];
x[0] = new Integer(0);
L3-Linguaggi Progammazione II-unina 17
Casting e conversioni di tipo - ricapitolazione
Conversioni di tipo implicite
Java consente due tipi di conversioni implicite
Variabili numeriche (“widening primitive conversion”,
promozione)
• Un tipo numerico puo’ essere convertito in un altro
con un range piu’ grande
• byte->char -> int, int ->long, int -> float, float
->double.
Variabili Riferimento
• Un riferimento ad una classe C può essere convertito
in un riferimento
ad una super classe di C
L3-Linguaggi Progammazione II-unina 18
Conversioni di tipo esplicite -casting
Variabili numeriche
Ogni tipo numerico puo’ essere esplicitamente
convertito in un altro tipo numerico (cast), con
possibile perdita di informazione (bit)
Variabili riferimento
Il cast di un riferimento ad uno oggetto è
sempre sintatticamente possibile, ma è
verificato a run time
L3-Linguaggi Progammazione II-unina 19
Esempi cast oggetti
class Person { ... }
class Military extends Person { ... }
class Worker extends Person { ... }
Person Person1, Person2;
Person1 = new Military(); //== ok
Person2 = new Worker(); //== ok
Person Person3;
Person3 = Person2; //== ?
Person3 = (Military) Person2; //== ?
Person3 = (Worker) Person1; //== ?
/* Es */
L3-Linguaggi Progammazione II-unina 20
Equivalenza col C++
• JAVA
Person3 = (Worker) Person1;
• C++
Person3 = dynamic_cast<Worker*>Person1;
L3-Linguaggi Progammazione II-unina 21