# Java/Errori e miti

Java
Copertina Tutti i moduli · Sviluppo
    CopertinaJava/Copertina
* Guida alla programmazione
** IntroduzioneJava/Introduzione
** Procurarsi il JDKJava/Procurarsi il JDK
** Dal sorgente all'esecuzioneJava/Dal sorgente all'esecuzione
** Il linguaggioJava/Il linguaggio
** Programmazione ad oggettiJava/Programmazione ad oggetti
** JavadocJava/Javadoc
** EserciziJava/Esercizi
** La macchina virtualeJava/La macchina virtuale
** Errori e mitiJava/Errori e miti
** Trucchi e consigliJava/Trucchi e consigli
* Specifica di linguaggio
** Tipi di datoJava/Tipi di dato
** Concetti fondamentaliJava/Concetti fondamentali
** OperatoriJava/Operatori
** Variabili localiJava/Variabili locali
** IstruzioniJava/Istruzioni
** Strutture di controlloJava/Strutture di controllo
** PackageJava/Package
** Classi e oggettiJava/Classi e oggetti
** OggettiJava/Oggetti
** MetodiJava/Metodi
** metodi (seconda parte)Java/Metodi/2
** ArrayJava/Array
** Modificatori di accessoJava/Modificatori di accesso
** EreditarietàJava/Ereditarietà
** Gestione delle eccezioniJava/Gestione delle eccezioni
** GenericsJava/Generics
** LessicoJava/Lessico
** GrammaticaJava/Grammatica
* Libreria standard
** Comunicazione serialeJava/Comunicazione seriale
** Stream
** Input e outputJava/Input e output
** Collections
** AWT e SwingJava/AWT e Swing
** Reflection
** SerializzazioneJava/Serializzazione
** SocketJava/Socket
* Argomenti avanzati
** MultithreadingJava/Multithreading
** Interblocco ricontrollatoJava/Interblocco ricontrollato
Modifica il sommario

## equals vs ==
### Quando utilizzare equals e quando utilizzare ==?

La risposta si trova pensando che il metodo equals confronta gli oggetti, mentre l'operatore == confronta i loro reference. Se abbiamo definito
allora
mentre
poiché si stanno confrontando due oggetti diversi.
Questo comportamento si spiega considerando che l'operatore == non confronta non i due oggetti, ma i loro reference. I reference di due oggetti diversi sono diversi a loro volta, di conseguenza l'operatore == restituisce false; ma i due oggetti rappresentano concettualmente lo stesso numero intero 0, quindi il comportamento più naturale per il metodo java.lang.Integer.equals è quello di restituire true.
In generale, ecco le principali differenze:
* equals determina se i valori simboleggiati dai due oggetti sono uguali; == determina se i due reference puntano allo stesso oggetto. (Di conseguenza, se == restituisce true, anche equals deve restituire true.)
* il metodo equals è un normale metodo, definito dalla classe di cui è istanza l'oggetto su cui lo stiamo invocando. Questo significa che
* se a è di tipo A e b è di tipo B e la classe A non è stata progettata per controllare i valori di B (ad es. perché appartenenti a due librerie diverse sviluppate da due società diverse), allora a.equals(b) restituirà false, anche se A e B fanno capo allo stesso concetto o a concetti idealmente simili;
** per conoscere l'esatto significato di a.equals(b) (cioè quando restituisce true e quando restituisce false), si deve fare riferimento alla documentazione della classe A; in mancanza, controllare la documentazione della superclasse (e così via, su per la gerarchia delle classi, fino ad arrivare ad Object).

## Metodi statici vs metodi di istanza: prestazioni

In linguaggi come il C, è consueto fare uso dei metodi cosiddetti virtuali solo quando necessario, utilizzando di norma solo metodi non virtuali. Questo permette di risparmiare memoria e cicli di CPU a run-time.
Tuttavia, in Java ha poco senso sostituire un metodo di istanza con uno statico, se non ci sono motivazioni di progettazione della classe dietro questa decisione. Ecco alcuni dei motivi:
* le macchine virtuali odierne adottano tecniche di ottimizzazione che rendono superfluo questo accorgimento: soprattutto la compilazione just-in-time e un'intensa ottimizzazione che viene applicata al bytecode, prima di essere eseguito o anche durante la sua esecuzione. Queste tecniche non vengono normalmente adottate per un programma C/C++;
* questo accorgimento altera il design della classe e l'usabilità del codice che viene scritto (peggiorandolo significativamente).

## break; negli switch

L'istruzione switch ha un difetto: è molto facile dimenticare di digitare l'istruzione break; al termine di una clausola case:
Il problema è che il compilatore non ha modo di sapere se questo è il reale intento del programmatore, perché questo codice è del tutto legittimo. Fortunatamente, però, esistono compilatori che controllano casi come questo e avvertono l'utente (con una warning, ovviamente, non con un errore) se incontrano una situazione in cui il programmatore potrebbe aver scritto qualcosa di diverso da ciò che era intenzionato a scrivere.

## Note

* ↑ (attenzione: rappresentano, non sono!)