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