Introduzione a Java - Roberto Mana
←
→
Trascrizione del contenuto della pagina
Se il tuo browser non visualizza correttamente la pagina, ti preghiamo di leggere il contenuto della pagina quaggiù
Tecnologie - Classe Quarta robertomana.it Introduzione a Java Introduzione a Java Rev Digitale 1.1 del 28/02/2018 Introduzione al linguaggio …………………………………………..……………………….….….. 2 Caratteristiche generali: …………………………………………..…………………………..….….. 2 Le basi del linguaggio Java …………………………………………..…………………………….….. 5 Gestione dell’input output …………………………………………..…………………………….….. 5 Tipi di dato nativi e le classi base …………………………………………..………………………….. 6 Boxing, Unboxing e Autoboxing …………………………………………..………………………….. 6 Le stringhe …………………………………………..……………………………………..…….….. 8 Il passaggio dei parametri …………………………………………..…………………………….….. 8 Perché le stringhe sono immutabili ……………………………………………………………………. 9 Principali metodi relativi alle stringhe ……………………………………………………..…….….. 10 La conversione fra i tipi …………………………………………..…………………………..….….. 10 Le istruzioni base: condizionali e cicli …………………………………………..……………….….. 11 Strutture dati semplici: vettori e matrici ………………………………………………………….….. 12 Gestione delle eccezioni …………………………………………..…………………………….….. 12 Gestione dei files di testo …………………………………………..…………………………….….. 13 Dichiarazione ed utilizzo delle classi …………………………………………..……………….….. 14 Ereditarietà …………………………………………..………………………………….……….….. 16 Overload e Override …………………………………………..……………………………….….. 16 Le librerie grafiche java - swing …………………………………………..………………..….….. 17 Istanza ed inizializzazione di una nuova fom …………………………………….…………….….. 19 Inserimento dei controlli all’interno della form ……………………………………………….….. 21 La gestione degli eventi …………………………………………..…………………………….….. 22 Gli eventi relativi alla form (window event) ……………………..…………………………….….. 24 La gestione del layout ……………………………………………..…………………………….….. 24 I principali controlli con relative Proprietà e Metodi ………………………………………….….. 26 Le finestre di Dialogo …………………………………………..……………………………..….. 29 pag 1
Tecnologie - Classe Quarta robertomana.it Introduzione a Java JAVA Introduzione Il linguaggio fu originariamente sviluppato da James Gosling e altri ingegneri presso Sun Microsystems e venne presentato ufficialmente il 23 Maggio 1995 in occasione del SunWorld ‟95 (convegni annuali di Sun Microsystems), come strumento per la creazione di programmi x Internet. Nel 1993 nasce il primo browser internet (mosaic) (anno di nascita di Internet) Nel 1994 nasce Internet Netscape. Nel 1995 Netscape Corporation annuncia la scelta di dotare il suo celeberrimo browser della Java Virtual Machine. Questo segna una rivoluzione nel mondo di Internet, consentendo al programmatore di sviluppare applet che, interagendo con la Java Virtual Machine, consentono di creare pagine web interattive a livello client (ovvero le applicazioni vengono eseguite direttamente sulla macchina dell'utente, e non su un server remoto). Gli utenti possono così utilizzare giochi direttamente sulle pagine web ed usufruire di chat dinamiche e interattive. Nel 1995 (giugno) Netscape Corporation rilascia la prima versione di JavaScript, un linguaggio che consente l‟inserimento di apposite istruzioni direttamente all’interno delle pagine HTML, istruzioni interpretate dal browser che consentono all‟utente di eseguire semplici interazioni con la pagina HTML. Il fatto che i due linguaggi abbiano nomi simili è solo una trovata di marketing, dovuta all‟alleanza tra Netscape e Sun. Si tratta in effetti di due linguaggi con Modello Oggetti differenti, di cui Java consente di sviluppare applicazioni indipendenti che devono essere compilate, mentre Java Script consente di scrivere all‟interno della pagina html semplici script testuali che saranno poi interpretati dal browser. Nel 2010 il marchio Java è stato acquisito da Oracle Corporation, che ne è attualmente detentore. Tutte le varie implementazioni devono sottostare alle specifiche definite nello standard. La versione attuale è Java 1.7 detto in realtà Java 2 La sintassi di base (strutture di controllo, operatori, etc) è identica a quella del C/C++, con lo scopo di facilitare il passaggio da un ambiente all‟altro. Il nome Java Il linguaggio fu battezzato con questo nome perché gli stessi tecnici durante il lavoro di sviluppo amavano discutere del progetto davanti ad una tazzina caffè Java (caffè indonesiano; Java è la principale isola dell‟Indonesia). La tazza di caffè fumante è rimasto il simbolo di Java. Caratteristiche del linguaggio Java Java è un linguaggio di programmazione orientato agli oggetti, specificatamente progettato per essere il più possibile indipendente dalla piattaforma di esecuzione, in cui il codice compilato possa essere eseguito su piattaforme diverse senza dover essere ricompilato Il prodotto della compilazione è infatti in un formato chiamato bytecode (precompilato) che può essere eseguito (in realtà interpretato) da una qualunque implementazione di un processore virtuale detto Java Virtual Machine. Tradizionalmente i passi necessari per eseguire una applicazione erano i seguenti : Sorgente -> Compilatore -> Binario Cambiando la piattaforma hw non funziona più. Non è portabile. Con l’interprete non c‟è più bisogno di compilare. L‟interprete legge ed esegue riga per riga. Consuma molte più risorse, per cui è molto più lento, ma consente la portabilità. pag 2
Tecnologie - Classe Quarta robertomana.it Introduzione a Java Un programma scritto su una piattaforma può poi essere eseguito su qualsiasi altra piattaforma dotata dell‟interprete. Altro vantaggio è che i programmi interpretati non hanno bisogno di installazioni, ma è sufficiente la presenza dell‟interprete. Già negli anni 80 con rm Cobol era stato utilizzato il concetto di interprete: edit file.cob rmcobol file.cob Java rappresenta una soluzione intermedia. La compilazione produce un codice intermedio che comunica con la Virtual Machine e non con il Sistema Operativo. E' sufficiente la presenza della Virtual Machine. La Controparte sta nella pesantezza. Per utilizzare programmi Java come Eclipse occorrono macchine prestanti con molta RAM. Sorgente -> Compilatore -> pseudoCodice -> Interprete Sorgente .java -> Compilatore javac -> byte code -> Interprete JVM $> edit pgm.java $> javac pgm.java : il compilatore produce il bytecode pgm.class $> java pgm : la JVM interpreta ed esegue il file pgm.class (scritto però senza estensione) Il compilatore produce un file con estensione .class che verrà interpretato dalla JVM. Java ad oggi è totalmente portabile. Esistono JVM per QUALSIASI SO. Creato un byte code con qualsiasi SO, questo potrà poi essere eseguito su qualsiasi altro SO. DotNet utilizza una tecnologia molto simile: Sorgente -> Compilatore -> MSIL -> Interprete CLR CLR = Common Language Runtime, macchina virtuale o framework. In realtà ogni funzione viene compilata Just In Time al primo accesso e tenuta in memoria. Esiste un CLR non ufficiale per Linux detto Mono Versioni La macchina virtuale esiste in diverse versioni: J2SE standard edition (tipica JRE Java Runtime Environment) J2EE enterprise edition versione più completa con tutte le librerie per lo sviluppo di applicazioni server (tipica SDK Software Development Kit detta anche JDK). J2ME micro edition (funzionalità ridotte per cellulari. Simbian (SO Nokia) aveva dentro una J2ME. Per sviluppare in Java non basta la JRE, ma ci vuole anche il compilatore. Occorre cioè l‟SDK Oggi JDK 7 che contiene compilatore + macchina virtuale versione Java 1.7 Evitare Open JDK. Versione Open di Oracle. Di solito non aggiornato e poco compatibile. I files JAR sono files contenenti un archivio compresso di classi java (libreria). Questo formato è direttamente utilizzabile dalla JVM senza necessità di decompressione. Le principali qualità di Java sono la semplicità, l‟elevata strutturalità e la robustezza Il garbage collector, tra le semplificazioni, è quella più palese. Un‟altra delle tante, meno evidente ma altrettanto importante, riguarda il passaggio dei parametri. I tipi primitivi possono essere passati solo per valore, gli oggetti solo per riferimento. Non esistono i record. pag 3
Tecnologie - Classe Quarta robertomana.it Introduzione a Java Installazione e Definizione del percorso del compilatore Andare sul sito di Oracle e scaricare gratuitamente la JDK 7 Dopo di che su Windows occorre configurare una variabile d‟ambiente che consenta di poter eseguire il compilatore JAVAC (che si trova in JDK 7 / BIN) da qualsiasi cartella. A tal fine: Pannello di Controllo / Sistema, ultima voce a sinistra “Impostazioni di sistema Avanzate”, sottofinestra Avanzate pulsante Variabili d’ambiente, selezionare Nuova e digitare: nome -> PATH valore -> %PATH%;C:\Program Files\Java\jdk1.7.0_45\bin Questa configurazione è legata all‟utente, per cui deve essere rifatta ogni volta che la macchina viene utilizzata da un nuovo utente. IDE Eclipse (oracle) Net Beans (fondazione Mozilla) Intellij IDEA Sublime (70 $) Tutti gratuiti. Per sviluppare come azienda occorre però pagare i diritti. Eclipse ha plug-in per tantissimi linguaggi di programmazione Net Beans è nato per sviluppare in Java. E‟ una specie di Eclipse leggermente semplificato. IntelliJ IDEA ha sostanzialmente sostituito Net Beans. Compila java, java script, CSS, android. versione Community gratuita. Non va installato. Si scarica un pacchetto che è sufficiente unzippare. Configurazione della variabile JAVA HOME Talvolta lanciando IntelliJ IDEA, eclipse o altro, non riescono a vedere la JVM. JAVA_HOME è una variabile di sistema che tutti questi ambienti vanno a leggere per sapere dove è memorizza la JVM. Sempre su variabili d‟ambiente, però questa volta su Variabili di Sistema, creare una NUOVA variabile: nome -> JAVA_HOME valore -> C:\Program Files\Java\jdk1.7.0_45 senza \bin Le librerie base (packages) java.lang.* Classi base (fra cui String) java.io.* Classi relative all‟Input / Output pag 4
Tecnologie - Classe Quarta robertomana.it Introduzione a Java Le basi del Linguaggio E‟ un linguaggio strettamente Orientato agli Oggetti. Ogni cosa è un oggetto. Anche il main è sostanzialmente un oggetto. Qualunque programma deve iniziare con la definizione di una classe. I nomi di classe hanno di solito la prima lettera Maiuscola. Un file di classe può contenere una sola classe pubblica che deve avere lo stesso nome del file in cui è contenuta. La classe principale NON può essere statica. Nel progetto possono esistere altre classi non pubbliche scritte indifferentemente prima o dopo rispetto alla classe pubblica. Nel caso in cui il file sorgente avesse un nome diverso rispetto a quello della classe pubblica, quando si compila, il compilatore crea un file di classe scritto in BYTE CODE avente come nome quello assegnato alla classe principale. La classe pubblica deve contenere un metodo pubblico statico denominato main() che rappresenta il punto di avvio del programma. La JVM cerca ed esegue il metodo statico main (String args[]) della classe richiamata, senza istanziare la classe che può eventualmente essere istanziata all‟interno del main stesso. Per compilare il file testuale occorre richiamare il compilatore mediante il comando javac Per lanciare in esecuzione il BYTE CODE occorre lanciare la JVM mediante il comando java seguito dal nome del file di classe contenente il ByteCode. L‟utility java è una entry point della JVM $> javac ese01.java $> java ese01 (scritto senza l‟estensione .class) Esercizio 1 : Input / Output da console public static void main (String[] args) { /* args.length contiene il numero di parametri */ System.out.print("Enter your name: "); String s = System.console().readLine(); System.out.println("\n Welcome " + s + " !!\n"); } Per evitare di anteporre ogni volta System si può eseguire all‟inizio il seguente import: import static java.lang.System.*; La classe System.console() in genere non è disponibile quando si lavora all‟interno delle IDE, dove occorre invece utilizzare: import java.io.*; BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); String s=br.readLine(); br.readLine()legge fino al \n che NON viene incluso nel buffer. try - catch try {} catch(Exception ex) { System.out.println(ex); System.exit(1); } pag 5
Tecnologie - Classe Quarta robertomana.it Introduzione a Java Try catch multipli try {} catch(IOException ex ) { System.out.println("Errore accesso al file"); } catch(SecurityException ex ) { System.out.println("Errore accesso al sensore GPS"); } L’oggetto Random import java.util.Random; Random rnd = new Random(); rnd.nextInt(B-A+1) + A Tipi nativi e classi base I tipi nativi char (1 byte o 2 byte se unicode ) byte (1 byte ) boolean ( 1 byte può avere valore true o false) short ( 2 byte ) int ( 4 byte – intero) long ( 8 byte – intero lungo) float (4 byte – valore a precisione singola) double ( 8 byte – valore a precisione doppia) decimal ( 16 byte – valore di solito per valute) Tra i tipi nativi è possibile eseguire un semplice cast inline: int n = 97; char c = (char) n; In Java non esiste il concetto di numero unsigned. Esistono comunque delle librerie esterne che implementano i tipi uint, ushort, ulong, ubyte. import static org.joou.Unsigned Boxing Il termine BOXING significa racchiudere una variabile primitiva dentro un oggetto. Per ogni tipo base esiste una corrispondente classe wrapper che consente di „incapsulare‟ il tipo primitivo nel relativo wrapper, meccanismo detto appunto Boxing. Lo scopo del Boxing è quello di poter utilizzare tipi primitivi all‟interno di oggetti (come ad esempio Liste) che accettano come elementi soltanto Oggetti. La classe Wrapper ha la prima lettera maiuscola. int n = 13; Integer x = new Integer (n); Double y = new Double (5.5); Character c = new Character („x‟); Boolean b = new Boolean (true); Java 1.6 realizza il cosiddetto AutoBoxing, che consente di istanziare gli oggetti direttamente tramite assegnazione, senza dover utilizzare il new. pag 6
Tecnologie - Classe Quarta robertomana.it Introduzione a Java Sostanzialmente Java 6 ridefinisce l’operatore di assegnazione facendo in modo che istanzi la classe passando al costruttore il valore dell‟assegnazione, dando vita così alla stesura di codice molto più fluido e maneggevole Integer x = 10; Double y = 5.5f; Non solo, ma anche quando si assegna un nuovo valore all‟oggetto, l‟operatore di assegnazione provvede automaticamente ad istanziare un nuovo oggetto all‟interno del quale viene „copiato‟ il valore dell‟altro oggetto, creando di fatto due oggetti indipendenti. Integer x = 10; Integer y = x; Unboxing Integer x = 10; int y = x; Autoboxing significa che le operazioni di Boxing e Unboxing vengono eseguite automaticamente dal compilatore del bytecode che si occupa di gestirle al posto nostro. L’operatore di Confronto Nel caso di istanze esplicite l‟operatore di confronto if(pt1 == pt2) verifica normalmente se i due puntatori stanno puntando allo stesso oggetto. Nel caso invece di istanze implicite definite mediante l‟Autoboxing, vengono confrontati non i puntatori ma il contenuto. Istanze esplicite: Integer n1 = new Integer(13); Integer n2 = new Integer(13); if(n1==n2) // false Trattandosi di due istanze esplicite indipendenti, vengono confrontati i puntatori che produrranno come esito FALSE. Autoboxing (istanze implicite): Integer n1 = 13; Integer n2 = 13; if(n1==n2) // true Questa volta, trattandosi di un autoboxing (istanze implicite) viene ridefinito anche l‟operatore == che confronta non più i puntatori ma i contenuti, producendo come esito TRUE. In C# questo problema non si pone in quanto per i wrapper numerici (così come per l‟oggetto String) l’istanza esplicita non è consentita, quindi l‟operatore di confronto potrà agire solo su istanze implicite. Viceversa il metodo equals( ) confronta il contenuto. Integer n1 = new Integer(13); Integer n2 = new Integer(13); if(n1==n2) // false if(n1.equals(n2)) // true pag 7
Tecnologie - Classe Quarta robertomana.it Introduzione a Java L’oggetto String Il tipo String esiste solo come oggetto, quindi con la S maiuscola. Così come le classi wrapper precedenti, anche la classe String, realizza il cosiddetto AutoBoxing, con la ridefinizione dell‟operatore di assegnazione, che ogni volta re-istanzia un nuovo oggetto passando al costruttore il valore dell‟assegnazione, facendo così apparire anche l‟oggetto String come un tipo nativo (scalare). String s1 = new String (“ciao”); // istanza esplicita String s2 = “ciao”; // istanza implicita if(s1==”ciao”) // false: questo “ciao” non è il “ciao” di s1 if(s2==”ciao”) // true Immutabilità delle stringhe Oltre all‟AutoBoxing, una ulteriore caratteristica delle stringhe, è che sono immutabili, cioè una volta istanziate non possono più essere modificate dall‟applicazione. Ogniqualvolta si tenta di assegnare un nuovo valore ad una stringa, viene automaticamente istanziata una nuova stringa ed il puntatore punterà al nuovo oggetto. La stessa cosa vale per tutte le precedenti classi wrapper, per le quali però, essendo „viste‟ quasi come variabili primitive, l‟immutabilità è molto più „naturale‟ ed intuitiva. L‟immutabilità delle stringhe è l‟elemento fondamentale per l‟utilizzo di tecniche di hash che consentono di velocizzare ed ottimizzare le ricerche all‟interno di raccolte come Liste, Dictionary, etc La definizione della classe String è la seguente : public final class String extends Object implements Serializable, Comparable, CharSequence { } la parola chiave final utilizzata davanti ad una variabile ha il significato di immutabile (costante), utilizzata davanti al nome di una classe significa cha la classe, oltre ad essere immutabile, è anche non-ereditabile. Il passaggio dei parametri Secondo una „Celebre‟ frase dello stesso Gosling, in Java i parametri possono essere passati solo per valore. I tipi primitivi possono essere passati solo per valore. Nemmeno i wrapper Integer, Double, Float, Boolean, etc. risolvono il problema in quanto, praticando l‟AutoBoxing, in corrispondenza di ogni assegnazione viene riassegnata al riferimento locale un nuovo oggetto, per cui in sostanza l‟oggetto base rimane invariato. Gli oggetti possono essere passati solo per riferimento. L'oggetto referenziato puo' essere quindi modificato dalla sottofunzione. Attenzione però che il riferimento stesso viene passato per valore, cioè viene fatta una copia del riferimento che viene ‘passata’ al chiamato attraverso lo stack. Quando una stringa (o un oggetto Integer) viene passata ad una qualunque funzione, nello stack viene passata una copia del puntatore all‟oggetto (String o Integer). Se si tenta di assegnare un nuovo valore a questo puntatore(s=”valore nuovo”, n=30), in entrambi i casi viene istanziato un nuovo oggetto ed il puntatore nello stack punterà al nuovo oggetto, Quando la funzione termina la copia del puntatore verrà rimossa dallo stack ed il puntatore del main continuerà a puntare alla vecchio oggetto. Questo può apparire scontato per gli oggetti della classe Integer (intuitivamente scalare), ma non è affatto scontato nel caso delle stringhe. pag 8
Tecnologie - Classe Quarta robertomana.it Introduzione a Java Nota : Perchè le String sono dichiarate come immutabili ? Ogni volta che viene creata una stringa essa viene posta in un‟ area di memoria ben definita, chiamata “string pool” accessibile tramite hash key numerica. La hash-key numerica viene calcolata dalla funzione di hash sulla base del contenuto della stringa (come avviene ad esempio per l‟MD5) e restituita al chiamante. Prima di inserire una stringa nel pool, la JVM effettua una ricerca hash per verificare se è già presente lo stesso valore letterale, che viene restituito senza essere replicato, altrimenti calcola e restituisce la corrispondente hash key numerica. Modificando la stringa cambierebbe la hash key numerica ed il meccanismo cadrebbe. Dopo di che all‟interno delle varie cache viene memorizzata non la stringa ma il suo codice hash numerico. L'hashing è alla base della ricerca indicizzata tramite chiave utilizzata in tutti i DB. Una ricerca basata su hashing è completamente diversa da una basata su confronti: invece di muoversi nella struttura data in funzione dell'esito dei confronti tra chiavi, si cerca di accedere agli elementi nella tabella in modo diretto tramite operazioni aritmetiche che trasformano le chiavi in indirizzi della tabella. Esistono vari tipi di algoritmi di hashing. In una tabella di hashing ben dimensionata il costo medio di ricerca di ogni elemento è indipendente dal numero di elementi. L'hashing è un problema classico dell'informatica; molti algoritmi sono stati proposti, studiati a fondo e impiegati in pratica. ll primo passo per realizzare algoritmi di ricerca tramite hashing è quello di determinare la funzione di hash: il dato da indicizzare viene trasformato da un'apposita funzione di hash in un numero intero compreso tra 0 ed m-1 che viene utilizzato come indice in una tabella (hash table) T [ 0 .. m-1 ] di lunghezza m. La funzione di hash in pratica stabilisce una corrispondenza tra l‟universo delle chiavi e le posizioni nella tabella hash. Idealmente, chiavi diverse dovrebbero essere trasformate in indirizzi differenti, ma poiché non esiste la funzione di hash perfetta, (ovvero totalmente iniettiva), è possibile che due o più chiavi diverse siano convertite nello stesso indirizzo. Il caso in cui la funzione hash applicata a due chiavi diverse genera un medesimo indirizzo viene chiamato collisione e può essere gestito in vari modi. La scelta di una buona funzione di hash è indispensabile per ridurre al minimo le collisioni e garantire prestazioni sempre ottimali. Il risultato migliore si ha con funzioni pseudo-casuali che distribuiscono i dati in input in modo uniforme. Molto spesso però, una buona funzione di hash può non bastare: infatti le prestazioni di una hash table sono fortemente legate anche al fattore di carico (load factor) calcolato come Celle libere / Elementi presenti e che indica la probabilità che ha un nuovo elemento di collidere con uno già presente nella tabella. Il load factor deve essere il più basso possibile (di solito un valore di 0.75 è quello ottimale) per ridurre al minimo il numero di collisioni. Ciò può essere fatto ad es ridimensionando l'array ogni volta che si supera il load factor desiderato (come fa automaticamente l‟oggetto List sia in Java che in C#) Principali metodi relativi alle stringhe s.length(); s.toUpperCase(); s.toLowerCase(); I metodi s1.equals(s2) e equalsIgnoreCase(s2) servono per confrontare il contenuto di due istanze esplicite ritornando true se hanno lo stesso contenuto (deep equals, opposto allo shallow equals di ==). Viceversa il test eseguito tramite == esegue uno shallow equals quindi fallisce. Non eseguire MAI il confronto fra stringhe tramite ==. Usare sempre .equals Il metodo (s1.compareTo(s2) == 0) è simile al precedente. Restituisce un int invece di un bool( più scomodo) ma consente anche di confrontare le stringhe alfabeticamente con maggiore e minore. pag 9
Tecnologie - Classe Quarta robertomana.it Introduzione a Java s = s.concat(String str) Concatena la sottostringa in coda alla stringa principale. Come + char c= s.charAt(int pos) Restituisce il carattere alla posizione indicata. b = s.contains(String str) Restituisce true se la stringa contiene la sottostring indicata. int pos = s.indexOf(String str, int fromIndex) Il primo parametro può essere un int che rappresenta il codice ascii di un carattere. int pos = s.lastIndexOf(String str, int fromIndex) s = s.substring(int beginIndex, int endIndex) Restituisce la sottostringa indicata (con endIndex escluso) String[] parts = s.split("-"); b = s.matches(String regex) Indica se la stringa fa match con la Regular Expression All‟interno di una stringa è possibile utilizzare il carattere \n. Il metodo .format consente di utilizzare i valori di formato tipici dell‟ANSI C: String s = “:” + String.format("%02d", myVar) + ":" cioè il valore intero di myVar viene visualizzato con almeno 2 cifre. La conversione fra i tipi Ognuna delle classi wrapper dei tipi base presenta dei metodi statici per la conversione del valore (contenuto all‟interno della classe) da e verso stringa. int n= Integer.parseInt(s); // restituisce un primitivo String s = Integer.toString(n); double x = Double.parseDouble(s); // restituisce un primitivo String s = Double.toString(x); boolean b = Boolean.parseBoolean("true"); String s = Boolean.toString(b); Es: Double x = 0; // ERRORE Double x = 0.0; // OK Double x = Double.parseDouble(“0”); Double x = Double.valueOf(0); ValueOf Sostanzialmente identico a parseInt parseDouble, etc, ma restituisce un Object invece che un primitivo String s = String.valueOf(x); // converte x in stringa, qualunque sia il tipo di x Double d = Double.valueOf(x); // converte x in Double, qualunque sia il tipo di x Talvolta utilizzato per convertire un tipo nativo nell‟object corrispondente : int x = 7; Integer b = Integer.valueOf(x); // converte x in Integer, qualunque sia il tipo di x L’istruzione switch E‟ identica all‟ANSI C. Può agire SOLO su variabili numeriche o singoli caratteri. Il risultato dello switch viene confrontato con ogni etichetta ed il programma esegue un salto all‟etichetta corrispondente, dopo di che l‟intero codice successivo viene eseguito fino a quando non si incontra un eventuale break. Dopo l‟ultimo case (o il default) il break può essere omesso pag 10
Tecnologie - Classe Quarta robertomana.it Introduzione a Java I cicli Sono identici all‟ANSI C con la possibilità di break e continue. Esiste anche il ciclo for each che presenta la seguente sintassi : String [] stringhe = { “stringa1”, “stringa2” }; for (String s : stringhe) visualizza(s) Vettori I Vettori sono classi „normali‟ a tutti gli effetti. Come tutti gli oggetti essi sono: Trattati per referenza Istanziabili solo tramite new I vettori possono essere dichiarati in diversi modi int myArray []; int [] myArray; int [] myArray = new int [10]; // come in C# E' possibile inizializzare i vettori in uno dei seguenti modi int [] myArray = { 1, 3 , 5, 6}; int [] myArray = new int [] { 1, 3 , 5, 6}; myArray.length => numero degli elementi del vettore. La lunghezza di un vettore, una volta creato, non puo' essere piu' cambiata. Se serve un vettore che possa crescere o decrescere dinamicamente, bisogna usare l'oggetto ArrayList Matrici Un vettore bidimensionale(o in generale multidimensionale) viene definito come un vettore di vettori: int mat[][] = new int[2][5] ; Si possono avere anche righe di lunghezza differente: int mat [][] = { {1, 3, 4},{2,4},{5}}; mat.length => 3 (numero di righe) mat [0].length => 3 - mat [1].length => 2 - mat [2].length => 1 Ellissi Se si passano ad un metodo più parametri tutti dello stesso tipo [ES sum (5,7,9,11)], il metodo può usare la sintassi detta ellipsis che consente di trattare i vari parametri come se appartenessero tutti ad un unico vettore: int sum (int ... n) { for (int i = 0; i < n.length; i++) totale += n[i]; return totale; } Le strutture Java non ha il tipo struct. Al suo posto si può usare una classe con sole proprietà pubbliche. pag 11
Tecnologie - Classe Quarta robertomana.it Introduzione a Java L’oggetto MAP In Java non esistono i vettori associativi. Al loro posto può essere utilizzato l‟oggetto Map che è molto simile e va istanziato come un Typed Object (cioè occorre definire il tipo) Map map = new HashMap(); map.put("name", "demo"); map.put("fname", "fdemo"); map.get("name"); Map è una interfaccia,e dunque non può essere istanziata direttamente, mentre HashMap è una delle classi che implementato l‟interfaccia Map e dunque può essere istanziata. Il vantaggio di utilizzare Map nella dichiarazione invece di HashMap è che diventa possibile modificare l‟oggetto istanziato (utilizzando ad esempio un diverso tipo di Map senza modificare il resto del codice). L’oggetto LIST Le Liste in Java, come in C #, sono Typed Object,. List listaCitta = new ArrayList(); for (int i = 0; i < 100; i++) listaCitta.add(“item”); for (int i = 0; i < listaCitta.size(); i++) alert(listaCitta.get(i); List è una interfaccia,e dunque non può essere istanziata direttamente, mentre ArrayList è una delle classi che implementato l‟interfaccia List e dunque può essere istanziata. Ci sono anche altre classi che implementano l‟interfaccia List in modo diverso da ArrayList, ad es la classe LinkedList List può comunque essere restituita da un metodo che esegua il cast da ArrayList. Gestione delle Eccezioni Qualunque istruzione che può generare errore DEVE essere racchiusa in un TRY – CATCH. Il catch riceve come parametro un oggetto e (error) che presenta i seguenti metodi: e.getMessage() restituisce il messaggio interno e.getCause() puntatore all‟oggetto causa (cioè in sostanza oggetto e genitore, se questo è stato passato come secondo parametro del throw) e.printStackTrace() visualizza il messaggio nello stackTrace In alternativa un metodo che possa sollevare eccezioni, può essere scritto senza TRY – CATCH con la sintassi : public void myMethod() throws Exception { } Se il metodo intende invece risollevare esplicitamente una eccezione all‟interno del catch, la sintassi è la seguente : throw new Exception("valore non valido", e); Il chiamante riceve un oggetto Exception, in cui getMessage() restituisce l‟ultimo errore, mentre getCause() può accedere all‟oggetto Exception precedente. Se lo desidera, il chiamante può fare una procedura ricorsiva per accedere, tramite e.getCause() successivi, a tutta la catena degli errori. Se il throw NON passa come secondo parametro l‟errore precedente, il metodo getCause() restituirà undefined. pag 12
Tecnologie - Classe Quarta robertomana.it Introduzione a Java I Files di testo L’oggetto File contiene tutte le informazioni relative al file passato come parametro al costruttore. File myFile = new File(”file.txt”) Sull’oggetto File sono disponibili i seguenti metodi: getPath, isFile, isDirectory, exists, delete, rename In realtà lettura / scrittura sul file possono essere eseguiti anche senza passare attraverso l‟oggetto File, ma partendo direttamente dal path. Lettura di un file import java.io.*; FileReader reader = new FileReader("file.txt"); BufferedReader br = new BufferedReader(reader); String s, testo; while((s=br.readLine()) != null) testo += s + “\n”; br.close(); reader.close(); Il metodo .readLine() legge una intera riga senza però restituire il \n finale che deve (eventualmente) essere aggiunto manualmente. Scrittura su un file L‟intero file costituito eventualmente anche da righe multiple può essere salvato in un colpo solo tramite il metodo .write(). FileWriter writer; writer = new FileWriter(“file.txt”, true); // append // writer = new FileWriter(“file.txt”, false); // overwrite, default writer.write("Lorem Ipsum\r\n"); writer.flush(); writer.close(); Per vedere se un file esiste ed è effettivamente un file e non una directory: File myFile = new File(path); if(myFile.isFile()) FileReader reader = new FileReader(myFile); else myFile.createNewFile(); Per leggere il contenuto di una cartella : File dir = new File(path); String [] vect = dir.list(); I Packages Rappresentano un meccanismo per organizzare le classi. Consentono ad esempio di creare classi pubbliche con nomi uguali. E‟ sufficiente inserirle all‟interno di package differenti. Al di fuori delle parole chiave del linguaggio e dei tipi nativi, tutto il resto è memorizzato all‟interno dei package. Tutte le classi principali sono raccolte all‟interno del package java.lang. pag 13
Tecnologie - Classe Quarta robertomana.it Introduzione a Java Eclipse Quando si crea un nuovo progetto, viene creato un nuovo package con il nome del progetto all‟interno del quale saranno posizionate tutte le classi appartenenti al progetto. Da un punto di vista del file system, il package corrisponde ad una cartella (avente lo stesso nome del package) all‟interno della quale verranno posizionati tutti i file relativi alle classi contenute nel package. E‟ possibile comunque in Eclipse rinomare il progetto (e quindi la cartella) senza che venga rinominato il package. Il file .classpath mantiene le necessarie corrispondenze. Il Garbage Collector ll garbage collector è un meccanismo che tiene traccia delle locazioni di memoria utilizzate e le libera solo quando non sono più necessarie. Java non permette al programmatore di accedere ad una qualsiasi locazione di memoria come avviene in C/C++. In Java non esistono puntatori con le stesse caratteristiche di quelli del C/C++. I puntatori in Java sono solo riferimenti impliciti ad oggetti allocati dinamicamente su uno heap e distrutti attraverso il meccanismo automatico di garbage collection. Il metodo finalize(), se presente all‟interno della classe, viene automaticamente richiamato dal garbage collector un attimo prima di deistanziare l‟oggetto. Può servire per eseguire operazioni di pulizia come ad esempio la chiusura di files eventualmente aperti o la disconnessione di connessioni di rete. Le Classi Le Proprietà rappresentano lo stato dell‟oggetto. Tendenzialmente devono essere sempre private. Il loro accesso può essere effettuato solo attraverso i metodi propertyGet() e propertySet(). Quindi in sostanza di una classe dall‟esterno si vedono SOLO i metodi (incapsulamento !). Le property con GET e SET automatiche esistono SOLO in Dot.Net I Metodi descrivono invece il comportamento dell‟oggetto, cioè le operazioni che l’oggetto sarà in grado di eseguire. Ad esempio animale1.corri(); Un metodo statico è un metodo che dipende dalla classe e non dall‟istanza. Le variabili interne ai metodi (compresi i parametri) sono dette variabili automatiche nel senso che, al termine, vengono automaticamente deallocate. Classi statiche In Java ogni classe può avere dei membri statici, ma non esiste il concetto di classe statica. Una classe deve sempre essere istanziata Qualificatori di Visibilità di Proprietà e Metodi private Visibile solo all‟interno della classe package default (da omettere). Visibile in tutte le classi interne al package (internal di C#) protected come package ma Ereditato nelle sottoclassi public Visibile da tutti pag 14
Tecnologie - Classe Quarta robertomana.it Introduzione a Java Qualificatori di Visibilità di una classe Sono gli stessi di cui sopra: private Visibile soltanto all‟interno della classe nella quale è stata dichiarata. package default (da omettere). Visibile da tutte le classi interne al package (internal di C#) protected come package ma Ereditato nelle sottoclassi public Visibile da tutti Una classe può essere anche abstract (must Inherits) o final (not inheritable, sealed in C#) Ogni file di classe può contenere una sola classe pubblica che deve avere lo stesso nome del file. Il costruttore Il valore di ritorno di un costruttore non può in nessun modo essere letto. Per questo si omette void, in quanto in realtà non può essere diversamente. Tra l‟altro il costruttore sarebbe anche static (viene richiamato quando l‟istanza ancora non esiste). All‟interno di una classe A è anche possibile dichiarare un metodo public void A() { } che diventa un normale metodo che però NON E‟ PIU‟ UN COSTRUTTORE. La parola chiave this usata all‟interno di una classe rappresenta un riferimento all‟istanza. Quando si accede ad un membro di classe con nome univoco (cioè quando non c‟è ambiguità) this può essere omesso. E‟ invece obbligatorio ad esempio all‟interno di un metodo che usa una vriabile locale con lo stesso nome. Un costruttore può richiamare un altro costruttore mediante la sintassi : this(par1, par2) Variabili Reference (riferimenti) Animale cane; cane è semplice riferimento non inizializzato. cane = new Animale(); viene istanziato un nuovo cane ed inizializzato il riferimento. Il termine pointer (puntatore) si usa nel caso di normali variabili native. Il termine handler (maniglia o riferimento) si usa per gli oggetti Esempio class A { private int x; public A() { x=3; } public void incrementa() { x++; } } class B { public B() { } public void incrementa(A a){ // riferimento alla classe a a.incrementa(); } } MAIN A a = new A(); a.incrementa(); // x diventa 4 B b = new B(); b.incrementa(a); // x diventa 5 pag 15
Tecnologie - Classe Quarta robertomana.it Introduzione a Java Ereditarietà Per ereditare una classe da un‟altra si utilizza l‟istruzione extends class Macchina2 extends Macchina{ private int costoKm; public Macchina2 ( ) { super(“fiat”, 600); costoKm=10; } public int calcolaSpesa(){ return costoKm*getKm(); } } Quando istanziamo macchina2 in realtà istanziamo anche una normale macchina per cui la sottoclasse Macchina2 deve in qualche modo richiamare il costruttore della classe da cui eredita passandogli i parametri necessari. La PRIMA riga del costruttore di macchina2 deve necessariamente richiamare come PRIMA istruzione, mediante la parola chiave super(),il costruttore della superclasse passandogli i parametri necessari. Overload e Override In Java è possibile eseguire implicitamente sia l‟overloading sia l‟overriding dei metodi senza nessuna dichiarazione aggiuntiva. Poer quanto riguarda l‟override è possibile anteporre al nuovo metodo la notazione @Override che è una annotazione aggiunta, facoltativa, da anteporre al metodo che esegue l‟override, per indicare al compilatore che il metodo su cui è posta sta effettuando unoverride di un metodo della sua superclasse. Lo scopo è quello di evitare errori. Se si crede di fare un override di un metodo che però nella classe base non dovesse esistere (con quella firma), il compilatore segnala un errore. Metodi di override inline In Java è possibile definire un metodo “al volo” in fase di creazione dell‟istanza. Macchina my = new Macchina("fiat", 700) { void visualizza () { System.out.println("Metodo disponibile per la sola istanza my"); } }; Il problema è che il nuovo metodo non può in alcun modo essere richiamato. Con questa tecnica è però possibile eseguire un override temporaneo di un metodo esistente. Nel caso dell‟override il metodo risulta richiamabile in quanto è già appartenente alla classe base. In corrispondenza del richiamo viene però richiamato il nuovo metodo definito inline. pag 16
Tecnologie - Classe Quarta robertomana.it Introduzione a Java La libreria grafica java-SWING Le librerie grafiche di base di Java sono le librerie AWT ( Abstract Window Toolkit ) contenenti tutte le classi e le interfacce fondamentali per la creazione di elementi grafici. AWT è stata inserita nelle API standard di Java per lo sviluppo di applicazioni GUI in modo veloce ed efficiente. In realtà le AWT sono abbastanza complicate da utilizzare. Sono allora state create altre librerie dette SWING che sono sostanzialmente un wrapper semplificato delle librerie AWT. Gerarchia delle classi della libreria java.swing pag 17
Tecnologie - Classe Quarta robertomana.it Introduzione a Java Elementi Base di Java Swing Visualizzazione di una MessageBox import javax.swing.*; JOptionPane.showMessageDialog(null, "Messaggio di esempio"); Firma completa: Object showInputDialog(Component parent, Object Message, String title, int messageType, Icon icon, Object[] SelectedValues, Object initialValue) Il parametro parent serve a specificare il frame principale; esso verrà bloccato fino al termine dell'interazione. Ponendo a null questo parametro la finestra verrà visualizzata al centro dello schermo e risulterà indipendente dal resto dell'applicazione. La classe Color this.setBackground(Color.cyan); Il beep toolkit.beep(); Terminazione dell’applicazione System.exit(0); pag 18
Tecnologie - Classe Quarta robertomana.it Introduzione a Java Istanza di una nuova form import java.awt.*; import javax.swing.*; import java.awt.event.* Una nuova form può essere creata in due modi: a) tramite una classe che eredita direttamente da JFrame (che è l‟equivalente della Windows Form) public class Form1 extends JFrame { JPanel pnl = new JPanel(); JButton btn1 = new JButton(); JButton btn2 = new JButton(); public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { public void run() { Form1 frm = new Form1 (); } }); } Proprietà e Metodi della form saranno accessibili come this.xxxxx b) tramite una classe ‘normale’ che dichiara ed istanzia un oggetto JFrame public class mainClass { JFrame form1 = new JFrame(); JPanel pnl = new JPanel(); JButton btn1 = new JButton(); JButton btn2 = new JButton(); public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { public void run() { mainClass frm = new mainClass (); } }); } Proprietà e Metodi della form saranno accessibili come form1.xxxxx In entrambi i casi: Il metodo statico main( ) funge da metodo Factory e provvede a creare una nuova istanza della classe base. Poiché il metodo statico main( ) si limita ad istanziare la classe, il riferimento frm viene perso non appena il main() termina, però la classe pubblica rimane istanziata ed in esecuzione come una nuova Form. Per cui è‟ anche possibile (preferibile) non dichiarare il riferimento e scrivere soltanto new Form1(); pag 19
Tecnologie - Classe Quarta robertomana.it Introduzione a Java Thread separati Una nuova Form viene di solito istanziata all'interno di un THREAD separato in modo che il processo principale possa continuare ad interagire con l‟utente („sentire‟ il mouse, etc.). I Thread in Java sono rappresentati mediante un oggetto chiamato Runnable. invokeLater() è un metodo statico della classe SwingUtilities che consente di eseguire un nuovo thread all‟interno del quale è possibile eseguire la creazione del thread stesso. All‟interno di invokeLater il programmatore deve semplicemente eseguire l‟override del metodo run : public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { public void run() { mainClass frm = new mainClass(); } }); } Inizializzazione della form all’interno del costruttore Le principali inizializzazioni da eseguire su una form, da eseguirsi tipicamente all‟interno del costruttore della classe, sono le seguenti: public Form1(){ form1.setSize(300, 200); form1.setLocation(300, 300); form1.setTitle("Form1"); form1.setLocationRelativeTo(null); form1.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); form1.setVisible(true); } } setSize definisce le dimensioni della form (larghezza e altezza) setLocation definisce la posizione x y di visualizzazione della form (spigolo in alto a sinistra) setVisible rende la form visible (di default è invisibile). setTitle definisce il contenuto della barra del titolo setLocationRelativeTo se sull‟oggetto corrente sono state definite il setSize o il setBounds, questo metodo consente di posizionare l‟oggetto rispetto ad un oggetto contenitore passato come parametro. Passando come valore null l‟oggetto viene posizionato a centro video (ma SOLO se a monte sono stati fatti il setSize o il setBounds). Questa riga ovviamente „copre‟ l‟impostazione effettuata da setLocation(). setDefaultCloseOperation fa sì che la chiusura della form (con click sulla x in alto a destra) comporti automaticamente anche la chiusura dell‟intera applicazione, compresa la JVM che altrimenti rimarrebbe in esecuzione. Centratura della Form sullo schermo tramite la classe Toolkit import java.awt.*; // java.awt.Toolkit e java.awt.Dimension; Toolkit toolkit = this.getToolkit(); Dimension size = toolkit.getScreenSize(); this.setLocation((size.width - this.getWidth())/2, (size.height - this.getHeight())/2); pag 20
Tecnologie - Classe Quarta robertomana.it Introduzione a Java Inserimento dei controlli all’interno della Form In Swing non si possono aggiungere nuovi controlli direttamente all‟interno del JFrame, ma controlli e Panel possono essere inseriti soltanto all‟interno del Container che rappresenta l‟area Client della Form. Questo Container rappresenta sostanzialmente un Panel a cui si può accedere mediante il metodo this.getContentPane(); Su qualunque Panel (compreso il Container) si può disegnare (forme, immagini...) oppure si possono aggiungere controlli esistenti esattamente come in C#. JPanel panel = new JPanel(); Container c = f.getContentPane(); c.add(pnl); oppure, dal momento che il Container è esso stesso un Panel : Container pnl = this.getContentPane(); Il metodo pnl.setLayout(null); consente di poter eseguire un posizionamento manuale assoluto dei controlli all‟interno del Panel stesso, ad esempio attraverso il metodo setBounds, disponibile per tutti i controlli e che consente di definire posizione e dimensioni del controllo. btn.setBounds(50, 60, 80, 30); // x, y, width, height Il metodo pnl.setLayout(new FlowLayout(FlowLayout.CENTER)); imposta come layout il FlowLayout, che è il default di tutti i Panel tradizionali ma non è il default del Container base. Il metodo pnl.setLayout(new GridLayout(nRighe, nColonne)); imposta una griglia. Il tipo di layout da assegnare ad un Panel, oltre che tramite il metodo set Layout(), può essere impostato anche passando il riferimento direttamente al costruttore: Panel pnl = new JPanel(new GridLayout(3,1)); Pannello Principale Il pannello principale utilizza come default un GridBagLayout abbastanza complicato. Questo Layout così come il GridLayout semplice consente una espansione automatica dei controlli in corrispondenza dell‟espansione della Form. Pannelli interni Utilizzano come default il il FlowLayout. Se anche si applica questi pannelli il GridLayout ma il pannello principale non è di tipo GridLayout, l‟espansione automatica dei controlli non avviene. Aggiunta di nuovi controlli all’interno di un Panel JLabel lbl=new JLabel("Etichetta"); pnl.add(lbl); Per ogni controllo, è sempre possibile passare al costruttore il VALUE del controllo stesso. Il metodo frm.pack(); Se dopo aver aggiunto i controlli sulla form si richiama il metodo frm.pack(), esso ridimensiona la form in modo da contenere esattamente i controlli inseriti, ciascuno con la propria dimensione. pag 21
Tecnologie - Classe Quarta robertomana.it Introduzione a Java La gestione degli eventi Ad eccezione di JLabel, tutti gli altri componenti Java generano molti eventi differenti. Anche gli eventi in Java sono degli oggetti, istanza della classe generica java.util.EventObject oppure di una sottoclasse più specifica. Ad esempio il pulsante JButton , quando premuto, genera un evento di classe ActionEvent. Quando si genera un qualsiasi evento, il RunTime istanzia una classe Event contenente tutte le informazioni sull‟evento (ad es chi generato l‟evento) ed „invia‟ tale oggetto ad un ascoltatore degli eventi (Listener) che deve essere stato preventivamente associato a quel controllo. L‟ascoltatore degli eventi deve implementare una adeguata interfaccia strettamente legata al tipo di evento. Nel caso di un ActionEvent (tipicamente il click ma anche il tasto INVIO su un TextBox) occorre associare un ActionListener il quale deve implementare il metodo void actionPerformed(ActionEvent e); definito all‟interno dell‟interfaccia stessa e che viene automaticamente eseguito in corrispondenza del verificarsi di un ActionEvent relativo al controllo. L‟associazione dell‟ ActionListener al controllo può essere eseguita in almeno tre modi diversi : 1) Definizione di un Listener locale associato al singolo controllo Nel momento in cui si aggiunge il Listener al controllo si può istanziare in loco una nuova classe specifica per quel controllo. btn.addActionListener( new ActionListener() { @Override public void actionPerformed(ActionEvent e) { System.exit(0); } }); La precedente rappresenta sostanzialmente una singola istruzione, la quale dovrà essere inserita all‟interno di una procedura (tipicamente al termine di InizializeComponent()). Questo approccio chiaramente non va bene nel caso in cui si desidera associare una medesima procedura di evento a più pulsanti. 2) Definizione di un Listener generico associabile a più controlli btn.addActionListener( new myListener()); class myListener implements ActionListener { @Override public void actionPerformed(ActionEvent e){ System.exit(0); } } Questa tecnica è probabilmente la migliore e più flessibile. Per ogni controllo associato occorre creare una nuova apposita istanza del Listener. pag 22
Tecnologie - Classe Quarta robertomana.it Introduzione a Java 3) Impostazione della Form (o del Panel) come Listener per gli eventi di tutti i controlli. E‟ infine anche possibile delegare la Form (o il Panel) ad implementerà lei l‟interfaccia ActionListener, nel qual caso la Form stessa al suo interno dovrà contenere l‟override del metodo actionPerformed. Nel momento in cui si dichiara il gestore di eventi di un qualsiasi controllo, occorre indicare la Form stessa come classe Listener. btn.addActionListener(this); Tutti gli eventi relativi a tutti i controlli potranno essere gestiti all‟interno della medesima procedura actionPerformed : public class Form1 extends JFrame implements ActionListener { ……………………………………………………………………………………………………………… ……………………………………………………………………………………………………………… @Override public void actionPerformed(ActionEvent e){ System.exit(0); } } Individuazione dell’evento specifico Nel caso in cui più controlli eseguano la stessa procedura di evento, è possibile individuare il sender utilizzando il metodo e.getSorce() che restituisce un RIFERIMENTO al controllo che ha scatenato l‟evento. if (e.getSource() == btn1) { } Il metodo e.getActionCommand() restituisce invece il value del sender. if (e.getActionCommand() == “rosso”) { } I principali tipi di evento ActionListener WindowListener MouseListener MouseMotionListener FocusListener ItemListener TextListener KeyListener pag 23
Puoi anche leggere