utilizzando gli oggetti Integer nell'API Java

7

Stavo rivedendo il codice di un collega e ho notato che stava usando Integer oggetti invece di int s in alcune API (getter, setter, variabili di istanza e parametri del metodo). Quando gli ho chiesto perché, mi ha detto che era perché voleva usare null per indicare uno stato non inizializzato, perché non c'era un buon valore predefinito.

Mi sento in conflitto. Da un lato, questa è una pratica comune con altri oggetti (lo so, Java 8 lo rende migliore con Optional<T> ). D'altra parte, sembra che la possibilità di un NullPointerException sia maggiore se i client API utilizzano il boxing automatico.

Questa è una buona pratica di codifica?

    
posta ykaganovich 11.03.2016 - 21:10
fonte

2 risposte

4

Questo dipende completamente dal dominio del problema e da come viene utilizzata l'interfaccia. Ho scritto interfacce in entrambi i modi.

Ho visto librerie SOAP che non consentono valori nulli, rendendo superfluo Integer .

Il rovescio della medaglia, ho usato Integer per i dati memorizzati nella cache (in particolare, menzioni "variabili d'istanza" nella tua domanda, non solo l'API):

public class Test implements Serializable {

  private transient Integer hash;

  public int hashCode() {
    if (hash == null) {
      hash = <time-consuming hash operation>;
    }
    return hash.intValue();
  }
}

In questo caso, l'oggetto viene utilizzato come una chiave in HashMap , quindi ha senso memorizzare nella cache un valore hash anziché ricalcolarlo più e più volte. Usare Integer significa che posso dire con certezza al 100% che ho già calcolato il valore o meno (al contrario del valore sentinel di String che in teoria può produrre una collisione hash).

Se un'API accetta un intero ma assume non null, si tratta di uno scenario fail-fast . Lancia un NullPointerException e dovrebbe farlo rapidamente. Il codice client che utilizza la tua API dovrebbe incontrare questa eccezione piuttosto rapidamente, rendendo più facile trovare e correggere i dati non validi durante il test.

Raccomando di usare Integer (magari con Facoltativo per chiarisci) per i dati opzionali e int quando è richiesto.

    
risposta data 11.03.2016 - 21:24
fonte
2

Qualsiasi valore che possa mai essere null è un NullPointerException in attesa di verificarsi. Qualsiasi codice che controlli tali valori deve eseguire un controllo aggiuntivo per null , che è facile da dimenticare per te e ancora più facile da dimenticare per gli altri utenti delle tue classi.

Per questo motivo ogni volta che ho un valore che può essere intenzionalmente sconosciuto o assente, uso Optional<T> da Java 8.

Nota che l'utilizzo di optional.get() restituisce NoSuchElementException su valori assenti che è solo leggermente più utile di un NullPointerException . Preferisco invece il pattern optional.ifPresent( [lambda-expression] );

Una soluzione alternativa per evitare NullPointerException s è Modello oggetto nullo . Quando hai una propria classe che può essere nullo, aggiungi anche un singleton che estende quella classe e rappresenta un'istanza non inizializzata o sconosciuta di quella classe e che implementa tutti i metodi pubblici per comportarsi in modo elegante.

    
risposta data 11.03.2016 - 21:22
fonte

Leggi altre domande sui tag