====== FAQ (Frequently Asked Questions) ====== [[start|Torna alla pagina principale di LPR-B-09]] ====== Eclipse ====== ===== Parametri di linea di comando in Eclipse ===== ** Come si settano i parametri d'avvio di Java su Eclipse (i "command line arguments")? ** Supponendo di avere una classe: public class Less { public static void main(String[] args) { ... } } compilata da shell con il comando: ->javac Less.java e avviata da shell con: ->java Less pippo.txt /usr/share/dict/words allora ''args.length'' sarà uguale a 2, mentre in ''args[0]'' sarà contenuta la stringa ''"pippo.txt"'' e in ''args[1]'' la stringa ''"/usr/share/dict/words"''. Per settare i parametri d'avvio di Java su Eclipse, cliccare in successione dal menù: run open run dialog arguments e inserire gli argomenti separati da spazio (nell'esempio precedente, ''pippo.txt'' ''/usr/share/dict/words'') ----------------------------------------------------------------- ===== Problemi con avvio di Eclipse ===== ** Come fare per avviare Eclipse se all'avvio segnala "workspace in uso"? ** A causa di una chiusura errata di Eclipse (ad es., tramite il comando ''"kill"'') può succedere che all'avvio mostri questo messaggio. Per sbloccarlo è necessario rimuovere il file ''.lock'' che si trova nella directory ''.metadata'' del workspace. Ad es.: -> rm [PATH]/workspace/.metadata/.lock ---------------------------------------------------------------------------------- ===== File .java e .class in Eclipse ===== ** Dove stanno i file .java e .class in un progetto creato con Eclipse e come si avvia da shell un programma creato tramite Eclipse? ** Al momento della creazione di un project in Eclipse, nella seconda schermata appare un'opzione "project layout": * use project folder as root for sources and class files * create separate folders for sources and class files che di default (modificabile) è settata sulla seconda scelta. In quest'ultimo caso, Eclipse crea due sottodirectory del progetto, chiamate ''"src"'' e ''"bin"''. La prima contiene i sorgenti, cioè i file ''.java'', la seconda gli "eseguibili" (in realtà, file bytecode con estensione ''.class''). Se si usano dei package, vengono create anche sottodirectory per ogni package sia sotto ''"bin"'' che sotto ''"src"''. Se, invece, si usa un'unica root directory, sia i file ''.java'' che ''.class'' sono nella directory del progetto. Supponiamo di aver creato in Eclipse il progetto ''"projectname"'' che ha un unico file ''"Foo.java"''. Nel caso in cui si avvii il programma da Eclipse, la current directory è in tutti i casi ''[PATH]/workspace/projectname/''. Nel caso in cui si avvi da shell (supponiamo, per semplicità, di non usare il parametro '''classpath'''), allora ci sono vari casi per avviare il programma: se si è scelto di usare directory separate per bin e src: e si definisce il package "foo": current directory = [PATH]/workspace/projectname/bin comando = java foo.Foo altrimenti: current directory = [PATH]/workspace/projectname/bin comando = java Foo con un'unica root directory per sorgenti e file .class: e si definisce il package "foo": current directory = [PATH]/workspace/projectname/ comando = java foo.Foo altrimenti: current directory = [PATH]/workspace/projectname/ comando = java Foo In tutti i casi (sia da Eclipse che da shell), se si vuole aprire un file usando un path relativo, ad es. tramite il comando '''FileInputStream in = new FileInputStream("pippo.txt");''', bisogna che il file ''"pippo.txt"'' stia nella current directory. Per ottenere il nome della current directory da Java, si può usare il comando: ''System.getProperty("user.dir");'' --------------------------------------------------------------------------------------------------------------------------------------------------------- ====== Java ====== ===== Convenzioni per i nomi in Java ===== * classi: prima lettera maiuscola class Raster; class ImageSprite; * interfacce: prima lettere maiuscola interface RasterDelegate; interface Storing; * metodi: prima lettera minuscola run(); runFast(); getBackground(); * variabili: prima lettera minuscola int i; char c; float myWidth; Per i nomi di classi, interfacce, metodi e variabili si usa la notazione "a gobba di cammello": ciascuna lettera iniziale di ogni parola interna al nome deve essere maiuscola. * costanti: tutte maiuscole, con parole interne separate dal simbolo underscore "_" static final int MIN_WIDTH = 4; static final int MAX_WIDTH = 999; static final int GET_THE_CPU = 1; * package: nomi minuscoli com.sun.eng com.apple.quicktime.v2 edu.cmu.cs.bovik.cheese Vedere anche: http://java.sun.com/docs/codeconv/ ===== Conversione dei parametri del main ===== ** Come convertire i parametri del main (stringhe) in interi/double? ** Supponiamo che il programma si aspetti due parametri, un intero e un double. In questo caso, si può fare così: int myInt = Integer.parseInt(args[0]); double myDouble = Double.parseDouble(args[1]); Può convenire mettere queste istruzioni all'interno di un ''try/catch'', per catturare eventuali eccezioni che sono dovute, ad esempio, a mancanza di input (''ArrayIndexOutOfBoundsException'') o errore di conversione (''NumberFormatException''), in maniera tale da settare comunque valori di default per le variabili ''myInt'' e ''myDouble'', oppure per ritornare un messaggio di errore all'utente. ===== Generazione di numeri random ==== Si può usare la classe ''java.util.Random'' in questa maniera: int MAX_VALUE = 100; Random randomGenerator = new Random(); // oppure: new Random(System.currentTimeMillis()); int randomInt = randomGenerator.nextInt(MAX_VALUE); **Attenzione**: il metodo ''nextInt(int n)'' ritorna un numero compreso tra 0 e ''n-1'' (nell'esempio, tra 0 e 99), per cui se si vogliono generare dei numeri compresi tra 1 e ''n'', si deve sommare 1 al valore ritornato. In alternativa si può usare il metodo statico ''Math.random()'', che ritorna un ''double'' in [0, 1), in questa maniera: int randomInt = (int) (Math.random() * MAX_VALUE); (anche in questo caso, ''randomInt'' sarà compreso tra 0 e 99). **Attenzione**: il seguente modo per generare un numero random è sbagliato: int randomInt = (int) Math.random() * MAX_VALUE; //sbagliato!!! Infatti, dato che l'operatore di cast ha precedenza rispetto a l'operatore di moltiplicazione, il numero ritornato da ''Math.Random()'' viene convertito a 0 e quindi il risultato della moltiplicazione è 0. ====== Callable ====== ===== Eccezioni lanciate da call() ===== ** Come si può gestire l'eventuale eccezione lanciata dal metodo ''call()''? ** A differenza del metodo ''run()'' di ''Runnable'', il metodo ''call()'' di ''Callable'' può lanciare una qualunque eccezione, anche controllata. L'eccezione eventualmente lanciata viene incapsulata in una eccezione di tipo ''ExecutionException'' che viene lanciata quando si esegue il metodo ''get()'' del ''FutureTask'' per ottenere il risultato di ''call()''. L'eccezione originale può essere ottenuta invocando il metodo ''getCause()'' sulla ''ExecutionException'' lanciata da ''get()''. ===== Quando termina una ''call()''... ===== ** Come si può essere avvisati quando termina una ''call()'' senza fare una ''get()'' bloccante? ** Come descritto nella API di ''FutureTask'', quando un ''FutureTask'' passa nello stato ''isDone'' perchè la ''call()'' termina l'esecuzione, viene eseguito il metodo (protected, void) ''done()'', che non fa niente. Questo metodo può essere sovrascritto in una sottoclasse in modo da notificare la terminazione a un altro thread in attesa dl risultato.