06/09/2008 14:40
Categorie:
java
Effective java Second Edition è un ottimo libro scritto da Joshua Bloch, rispetto alla prima edizione è stata aggiunta una ampia parte relativa alle features introdotte in java 1.5. Il libro è diviso in item, ogni item può essere letta indipendentemente dalle altre anche se ci sono molti riferimenti incrociati. Questo libro dà per scontata una buona conoscenza di java e quindi è destinato a chi ha già un po' di esperienza nello sviluppo in java.
Gli argomenti trattati sono molti, i vari item sono divisi nei seguenti capitoli:
- Classi e interfacce
- Generics
- Enum e annotation
- Metodi
- Consigli generali
- Eccezioni
- Concorrenza
- Serializazzione di oggetti
Capire a fondo ogni item permette nelo sviluppo di tutti i giorni di
evitare molti bug "subdoli" che a prima vista non vengono rilevati. Ecco un elenco molto conciso di alcuni degli argomenti trattati (ogni riga meriterebbe un post completo in questo blog):
- minimizzare lo scope delle variabili locali: non dichiarare mai le variabili all'inizio di un metodo ma dichiararle sempre al momento del primo utilizzo
- equals e hashCode: quando in una classe si sovrascrive il metodo equals deve essere sovrascritto anche il metodo hashCode altrimenti si hanno problemi nell'uso di collection come HashMap e HashSet
- Equals gerarchie: il metodo equals deve essere riflessivo, simmetrico e
transitivo, è impossibile avere queste tre proprietà quando si ha a che
fare con una gerarchia di classi
- preferire la composizione all'ereditarietà: usando l'ereditarietà si crea un forte accoppiamento fra la classe base e la classe derivata, in molti casi è meglio ridurre questo accoppiamento usando la composizione
- eccezioni runtime: usare checked exception per errori recuperabile, eccezioni runtime per tutti gli altri, le eccezioni runtime non sono da "svogliati" che non hanno voglia di gestire le eccezioni
- generics: se si scrive codice che usa classi generiche che non genera unchecked warning si ha la certezza che runtime non ci saranno ClassCastException. Per evitare warning è utile conoscere bene come utilizzare le wildcard, in questo libro sono spiegate varie tecniche interessanti. Sul sito della sun è disponibile gratuitamente il pdf del capitolo del libro che parla dei generics. Per approfondire ulteriormente l'argomento un ottimo libro è java generics and collections
- clone e final: una implementazione corretta del metodo clone richiama il metodo clone di Object e assegna ai campi non primitivi non immutabili il clone del corrispondente clone. Ma se uno di questi campi è definito come final? Semplice, il compilatore dà un errore, come succede in questa semplice classe:
public class Persona implements Cloneable {
private final Indirizzo indirizzo;
protected Persona clone() {
try {
Persona c = (Persona) super.clone();
c.indirizzo = indirizzo.clone();
return c;
} catch (CloneNotSupportedException e) {
throw new AssertionError();
}
}
}
- sottoclassi e array: un array di stringhe è una sottoclasse di un array di object, ciò può portare ad errori runtime:
Object[] array = new String[2];
array[0] = new Integer(2);
- long e double non sono thread safe: se due thread accedono in contemporanea a una variabile di tipo long o double il risultato può essere non corretto
- se si ha bisogno di calcoli esatti usare BigDecimal e non float o double: questa cosa è abbastanza conosciuta (chi ha lavorato in ambito bancario lo sa bene) ma sinceramente l'avevo sempre vista quasi come una "precauzione eccessiva". Dopo che ho visto questo esempio ho cambiato idea:
System.out.println(1.00 - 9 * .10);