































































Studia grazie alle numerose risorse presenti su Docsity
Guadagna punti aiutando altri studenti oppure acquistali con un piano Premium
Prepara i tuoi esami
Studia grazie alle numerose risorse presenti su Docsity
Prepara i tuoi esami con i documenti condivisi da studenti come te su Docsity
Trova i documenti specifici per gli esami della tua università
Preparati con lezioni e prove svolte basate sui programmi universitari!
Rispondi a reali domande d’esame e scopri la tua preparazione
Riassumi i tuoi documenti, fagli domande, convertili in quiz e mappe concettuali
Studia con prove svolte, tesine e consigli utili
Togliti ogni dubbio leggendo le risposte alle domande fatte da altri studenti come te
Esplora i documenti più scaricati per gli argomenti di studio più popolari
Ottieni i punti per scaricare
Guadagna punti aiutando altri studenti oppure acquistali con un piano Premium
Una panoramica dettagliata sulla struttura di un programma Java, dal package al sistema di gestione degli errori e delle eccezioni, passando per la programmazione concorrente e la creazione di thread. Vengono spiegati concetti come il package, la compilation unit, il linguaggio Java in dettaglio, la visibilità e l'importazione di classi, il gestione degli errori, le eccezioni, i processi e i thread, la preemption e la cooperazione, la creazione di nuovi thread e la sincronizzazione.
Tipologia: Appunti
1 / 71
Questa pagina non è visibile nell’anteprima
Non perderti parti importanti!
































































Java è in parte compilato ed in parte interpretato.
All’inizio il sorgente viene compilato del COMPILATORE tramite il comando:
javac programma.class ,
che genera un file chiamato programma.class contenente il byte code. E’ la traduzione del programma in un linguaggio intermedio
Il byte code può essere interpretato su qualsiasi piattaforma che supporta Java tramite il comando:
java programma
programma.java
javac programma.java
programma.class
public class HelloWorld { public static void main(String args[]){ System.out.println(“Hello world!”); } }
Il main non è una funzione, è un metodo. Quando eseguo un programma java, devo lanciare il programma che contiene il metodo main.
Nota: Per il debug, si consiglia di mettere un metodo main in ogni classe così da poter fare il testing delle unità.
public class HelloWorld {
specifico il metodo di accesso alla classe
public static void main(String args[]){
può esserci o meno davanti ad un metodo a attributo, indica che sono metodi o attributi di classe.
Per gli attributi: ne esiste uno per ogni classe, non uno per ogni oggetto (potrebbe essere ad esempio usato per implementare le variabili globali), un esempio classico è dato dall’implementazione di un contatore di oggetti allocati.
I metodi static possono essere usati per modificare attributi static oppure anche per realizzare delle librerie di funzioni.
c:\classes>javac HelloWorld.java c:\classes>java HelloWorld HelloWorld! c:\classes>
Un programma Java è organizzato come un insieme di classi Classi diverse possono essere raggruppate all’interno della stessa “Compilation unit” che hanno un estensione .java
Il programma principale è rappresentato da un metodo speciale (main) della classe il cui nome coincide con il nome del programma
import java.awt.; package examples, class HelloWorldWindow { public static void main(String args[]) { Frame f=new Frame("HelloWorldWindow"); f.add(new Label("HelloWorld!",Label.CENTER),"Center"); f.pack(); f.setVisible(true); } }*
import : importa caratteristiche particolari di un particolare package.
package examples : il programma è dichiarato nel package examples. Il file deve essere nella directory examples. lo compilo li e lo eseguo (oppure in una dir esterna, ma riferendomi al nome comple to della classe che è: examples.HelloWorld)
Un package definisce uno spazio dei nomi; consente di avere un meccanismo per strutturare lo spazio dei nomi (posso ad esempio definire due classi con lo stesso nome in package diversi). Vincola inoltre il modo in cui i file sono memorizzati nel file system.
I package possono essere annidati: ad esempio
myProg
examples lectures
accederei ad una classe di examples con la notazione puntata: myProg.examples.NomeClasse
c:\classes>cd examples c:\classes\examples>javac HelloWorldWindow.java c:\classes\examples>cd .. c:\classes>java examples.HelloWorldWindow c:\classes>
Tipi numerici:
Altri tipi:
I tipi primitivi sono allocati nello stack (sempre), mentre in C++ li potevo allocare nello heap mediante i puntatori.
Per allocare i tipi primitivi nello heap si possono usare i wrapper, che mi permettono di avvolgere all’interno di una classe un tipo primitivo.
byte un_byte; int a, b=3, c; char c=‘h’, car; boolean trovato=false;
o Classi
o Interfacce
I tipi oggetto sono sempre allocati nello heap (mentre in C++ se li definivo come tipi normali, venivano allocati sullo stack e venivano allocati nello heap solo con la new )
Anche gli array sono considerati tipi riferimento e sono allocati nello heap.
Dato un tipo T (predefinito o definito dall’utente) un array di T è definito come: T[]
Similmente sono dichiarati gli array multidimensionali: T[][] T[][][] …
Esempi: int[] //array di interi float[][] //matrice di float Persona[] //array di elementi riferimento
Dichiarazione: int[] ai1, ai2; float[] af1; double ad[]; Persona[][] ap;
Inizializzazione: int[] ai={1,2,3}; double[][] ad={{1.2, 2.5}, {1.0, 1.5}}
Posso anche inizializzarli al volo.
TIPI ARRAY: ALLOCAZIONE DI MEMORIA
In mancanza di inizializzazione, la dichiarazione di un array non alloca spazio per gli elementi dell’array.
L’allocazione si realizza dinamicamente tramite l’operatore:
new
La dimensione dell’array deve essere nota. Esiste una classe Vector che consente di avere più oggetti dello stesso tipo, senza dover dichiararne il numero.
Esempi: int[] i=new int[10], j={10,11,12}; float[][] f=new float[10][10]; Persona[] p=new Persona[30];
Se gli elementi non sono di un tipo primitivo, l’operatore “new” alloca solo lo spazio per i riferimenti. In C++ se dichiaro una variabile senza inizializzarla, a questa non viene assegnato nessun valore, in Java viene assegnato un valore di default che per i riferimenti è “null”.
L’istruzione:
float f[] = new float[20];
crea un oggetto di tipo array di float e alloca spazio per 20 float
L’istruzione:
Person p[] = new Person[20];
crea un oggetto di tipo array di Person e alloca spazio per 20 riferimenti a oggetti di tipo Person
Non viene allocato spazio per gli oggetti veri e propri
Diverso dal C++, in cui potrei scrivere Person p[20]; poiché l’array è allocato staticamente ed ogni cella di memoria contiene lo spazio per un oggetto di tipo persona. Se faccio allocazione dinamica con la new è come Java.
person
f
Una nuova classe viene definita nel seguente modo:
class
Esempio: class Automobile {... }
Le due classi C sono distinte. Il package permette di restringere la visibilità della classe.
public class C
C è visibile a tutte le classi che hanno importato il package dove c’è C
class C
C è visibile solo dentro il package in cui è definita.
In un package ci deve essere almeno una classe public che serva da interfaccia con l’esterno. Se non definiamo nessun package, le classi sono messe in un package di default e sono tutte tra di loro visibili.
Gli attributi costituiscono lo “stato” degli oggetti appartenenti ad una classe Gli attributi si definiscono usando la stessa sintassi della dichiarazione di variabili
Esempio class Automobile { String colore, marca, modello; int cilindrata, numPorte; boolean accesa; }
class C class C
package p package q
Le istanze di una classe si chiamano oggetti
Ogni variabile il cui tipo sia una classe (o un interfaccia) contiene un riferimento ad un oggetto
Ad ogni variabile di tipo riferimento può essere assegnato il riferimento null: Automobile a=null;
Regola per il passaggio parametri:
ESEMPIO
Abbiamo una classe che definisce un metodo
class NomeClasse{ … m (int x, Stack s) { … } … }
Invochiamo:
NomeClasse o = new NomeClasse(); int 5; Stack s1 = new Stack(20); o.m(y, s1);
Vediamo cosa succede
Nell’AR di m, davo avere due celle, una per x ed una per s
Il 5 viene copiato nel parametro formale x, mentre per s copiamo il valore del puntatore.
x
s
m( )
y s
s viene passato per riferimento.
L’accesso ad attributi e metodi di un oggetto per il quale si abbia un riferimento si effettua tramite la “notazione punto” (inglese: dot-notation )
Esempio: Automobile a; .... if(a!=null){ a.accendi(); a.dipingi(“Blu”); }
Nella definizione di un metodo ci si riferisce ad attributi e metodi dell’oggetto sul quale il metodo sia stato invocato direttamente (senza notazione punto)
Esempio class Automobile { String colore; void dipingi(String col) {colore=col;} ... }
x 5
s
m( )
y s
Nuovi oggetti sono costruiti usando l’operatore new
Automobile a=new Automobile();
La creazione di un oggetto comporta l’invocazione di un particolare metodo dell’oggetto chiamato costruttore.
Il costruttore svolge due operazioni fondamentali: l’allocazione della memoria necessaria a contenere l’oggetto l’inizializzazione dello spazio allocato
A differenza del C++, in Java non è necessario deallocare esplicitamente gli oggetti. Di ciò si occupa il garbage collector.
Nella definizione di una classe è possibile specificare uno o più (vedi overloading) costruttori
Se non si definisce nessun costruttore, il compilatore fornisce il costruttore di default (senza parametri), che svolge le seguenti funzioni:
NOTA: Se in una classe definiamo un costruttore con pa rametri, nelle classi figlie non posso utilizzare il costruttore di default.
class Automobile { String colore, marca, modello; int cilindrata, numPorte; boolean accesa;
Automobile() { colore=marca=modello=null; cilindrata=numPorte=0; }
Automobile(String colore, String marca, String modello) { this.colore=colore; this.marca=marca; this.modello=modello;
cilindrata=numPorte=0; }
void accendi() {accesa=true;} boolean puoPartire() {return accesa;} void dipingi(String col) {this.colore=col;} }
A volte è comodo fattorizzare il codice dei costruttori
È possibile invocare un costruttore dall’interno di un altro tramite la notazione: this(
Esempio: class Persona { String nome; int eta;
Persona(String nome) {this.nome=nome; eta=0;}
Persona(String nome, int eta) { this(nome); this.eta=eta; } }
Per evitare di riscrivere il codice.
this(nome); //richiama il costruttore che gestisce il nome (il costruttore associato all’oggetto corrente)
Sintassi:
static <definizione dell’attributo o metodo>
Un attributo di classe è condiviso da tutti gli oggetti della classe
Si può accedere ad un attributo di classe senza bisogno di creare un oggetto tramite la notazione :
Poiché sono statici, i metodi di classe può essere invocato senza bisogno di creare un oggetto tramite la notazione: