javac
e java
.java
) e file di classi compilate (.class
)Il codice sorgente che un programmatore scrive, generalmente è condiviso con altre persone (del proprio team, ma anche persone esterne al team o la community)
Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live. Code for readability. John Woods [disputed]
Linguaggi diversi, regole di stile diverse!
Le prassi di riferimento per Java sono disponibili qui:
Ad esempio:
Notare che sono sempre consistenti!
Le parentesi graffe vanno sempre “all’egiziana” (Egyptian brackets)
// mini guida: PascalCase, camelCase, snake_case, kebab-case
package
usano sempre e solo lettere minuscole e numeri, senza underscore (_
)camelCase
: myVariable
, myMethod()
, myObject.myField
PascalCase
(cominciano per maiuscola): SomeClass
static final
(costanti di classe) usano SNAKE_CASE
, ma solo con lettere maiuscoleOvviamente può essere difficile fare tutto a mano: esistono strumenti automatici a supporto, che introdurremo nelle prossime lezioni…
javac
.java
), generando classi sotto forma di
file in bytecode con estensione .class
nella medesima directorysrc
, per i file sorgenti (.java
)bin
, contenente le classi compilate (.class
)javac
-d
: consente di specificare la cartella destinazione in cui compilare i file .java
javac -d "<CARTELLA DESTINAZIONE>" "<FILE JAVA>"
javac -d "<CARTELLA DESTINAZIONE>" "<ELENCO DI FILE JAVA>"
È possibile anche utilizzare la wildcard (*
) invece di elencare tutti i file!
sh
e shell derivate si possono usare wildcard in più punti del path,
progetti/*/src/*.java
elenca tutti i file con estensione java dentro ciascuna cartella
src
di ciascuna cartella dentro progetti
Il risultato della compilazione di sorgenti Java sono una o più classi
-d
di javac
),
ogni compilato .class
sarà creato in un
sottopercorso di cartelle che corrisponde al percorso del package dichiarato per la classe corrispondenteC.java
definente una classe foo.bar.C
,
con javac -d <DEST> path/to/C.java
il compilato sarà creato in <DEST>/foo/bar/C.class
Quando si va ad eseguire (comando java
), si eseguono classi, non files
Possiede un elenco di percorsi a partire dai quali i file compilati possono essere trovati
Cerca nei suddetti percorsi (in ordine) la classe che gli serve
/a/b/c
e ../foo
e si chiede di eseguire il programma definito nella classe Program
,
allora la JVM cercherà di caricare la classe da /a/b/c/Program.class
e, se non la trova, da ../foo/Program.class
Se non specificato, il classpath di Java include automaticamente:
java.lang.Math
Possono essere aggiunte directory al classpath
-cp
(o, equivalentemente, -classpath
), seguita da un elenco di percorsi
:
su ;
su "
)
javac -d bin -cp "lib1:lib2:lib3" src/*.java
src
, mettendo i compilati dentro bin
.
In compilazione, potrà linkare tutte le classi che si trovano nelle cartelle lib1
, lib2
e lib3
:
la compilazione avrà successo anche se le classi che stanno venendo compilate usano librerie contenute nelle cartelle precedenti.javac -d bin -cp "lib1;lib2;lib3" src/*.java
java -cp "bin:lib1:lib2:lib3" MyClass
main
della classe MyClass
. Cercherà questa classe e tutte quelle collegate all’interno delle cartelle bin
, lib1
, lib2
e lib3
.java -cp "bin;lib1;lib2;lib3" MyClass
È buona norma organizzare i sorgenti in modo da rappresentare su filesystem la struttura dei package. Si noti però che (dato che il compilatore lavora su file) questa scelta non è teoricamente obbligatoria!
Quando ad essere compilata è una classe dichiarata in un package, il compilatore riproduce la struttura dei package usando delle directory
-d
L’esecuzione è identica al caso precedente, si faccia solo attenzione ad usare l’intero nome della classe, che in Java include anche il nome del package!
Supponiamo di avere in mano la seguente classe:
package oop.lab02.math;
public class UseComplex {
public static void main(final String[] args) {
final ComplexNum c1 = new ComplexNum();
c1.build(1, -45);
final ComplexNum c2 = new ComplexNum();
c2.build(2, 8);
System.out.println(c1.toStringRep());
System.out.println(c2.toStringRep());
c1.add(c2);
System.out.println("c1 new value is: " + c1.toStringRep() + "\n");
}
}
ed eseguiamo javac UseComplex.java
. Cosa otteniamo?
Otteniamo degli errori!
src\oop\lab2\math\UseComplex.java:6: error: cannot find symbol
ComplexNum c1 = new ComplexNum();
^
symbol: class ComplexNum
location: class UseComplex
src\oop\lab2\math\UseComplex.java:6: error: cannot find symbol
ComplexNum c1 = new ComplexNum();
^
symbol: class ComplexNum
location: class UseComplex
src\oop\lab2\math\UseComplex.java:8: error: cannot find symbol
ComplexNum c2 = new ComplexNum();
^
...
ComplexNum
per poterla
linkare e per poter compilare una classe che la riferisceComplexNum
Come risolviamo?
-cp
in fase di compilazioneComplexNum
(ovvero non il sorgente)
oop/lab02/math/ComplexNum.class
può essere individuata nel
classpath di javac
!UseComplex.java
nel percorso src/oop/lab02/math/
ComplexNum
con destinazione (di partenza) lib/
javac -d bin -cp lib src/oop/lab02/math/UseComplex.java
javac -d bin -cp lib src/oop/lab02/math/UseComplex.java
javac
$\Rightarrow$ Invocazione del compilatore-d bin
$\Rightarrow$ -d
determina la destinazione. Vogliamo compilare dentro la cartella bin
-cp lib
$\Rightarrow$ -cp
consente di aggiungere percorsi al
classpath. Noi vogliamo cercare le classi che ci servono, oltre che nella
posizione corrente e nelle librerie java, anche dentro lib
src/oop/lab02/math/UseComplex.java
$\Rightarrow$ Il file che vogliamo compilareAvendo come riferimento l’esempio precedente, proviamo ad eseguire.
UseComplex
dobbiamo dire alla JVM, tramite -cp, dove trovare:
ComplexNum
UseComplex
-cp
due percorsi, usando il separatore:
:
su ;
su java -cp bin:lib oop.lab02.math.UseComplex
java -cp bin;lib oop.lab02.math.UseComplex
(Windows)javac
e java
Visto che all’esame il loro utilizzo è richiesto, è necessario imparare a memoria le opzioni di java
e javac
?
Entrambi i comandi (e praticamente tutti i comandi Unix) hanno con loro un’opzione che consente di stampare a video un help. Provate
java -help
javac -help
Gli help stampano abbondante testo con le relative istruzioni e a me serve una riga, davvero devo imparare a leggere e capire un help?
È molto facile dimenticarsi la sintassi delle opzioni di comandi che non si usano spesso. È molto più facile imparare a destreggiarsi in un help che andare a tentativi o ricordare cose a memoria.
La maggior parte dei comandi supporta degli argomenti
Ad esempio, quando eseguite javac -d bin MyClass.java
gli argomenti sono le seguenti tre stringhe:
-d
bin
MyClass.java
int main()
come coppia di char **
e int
,
rappresentanti rispettivamente un riferimento all’area di memoria dove sono salvati i parametri ed il numero dei suddetti.La gestione è un po’ *più semplice rispetto a *C perché che gli array si portano dietro la loro dimensione come campo
In Java la signature del metodo main()
è una univoca: public static void main(String [])
,
mentre in C sia int main(void)
che int main(char **, int)
sono accettabili.
String[] args
) che il metodo main()
prende in ingressoSia $n$ il numero di elementi dell’array ed $x_i$ l’elemento all’indice $i$ dell’array, e $\mu$ la media dei valori del suddetto array. La varianza $\sigma^2$ può essere calcolata come:
$\sigma^2 = \frac{\displaystyle\sum_{i=0}^{n-1}(x_i - \mu)^2} {n}$