2010-07-13 13 views
16

Sto rivedendo un manuale di buone pratiche e codice di raccomandazione java credo sia dubbio.Java: "xx" .equals (variabile) migliore di variable.equals ("xx"), TRUE?

Recomendation:

String variable; 

"xx".equals(variable) // OK 

variable.equals("xx") //Not recomended 

Perché impedisce comparsa di NullPointerException che non sono controllati

E 'vero?

+3

Se si sta scrivendo un manuale tecnico, è necessario preoccuparsi di problemi grammaticali più grandi di una semplice avvertenza di codifica come questa. – Zak

+6

@Zak, che non è veramente rilevante. Come sai che il manuale sarà in inglese? Forse Xerg scrive fluentemente in un'altra lingua e sta creando il manuale in quella lingua. Tutti quelli che hanno risposto sono riusciti a capire quale fosse il punto cruciale della domanda. –

+1

Non sto scrivendo alcun manuale. Sto solo controllando. Scusa il mio inglese, sono un lettore migliore dello scrittore. – Xerg

risposta

23

Questa è una tecnica molto comune che fa sì che il test restituisca false se la variabile è nullo invece di lanciare uno NullPointerException. Ma immagino che sarò diverso e dirò che non lo considererei una raccomandazione che dovresti sempre seguire.

  • Penso che sia qualcosa di cui tutti i programmatori Java dovrebbero essere consapevoli in quanto è un linguaggio comune.
  • È anche una tecnica utile per rendere il codice più conciso (è possibile gestire il caso nullo e non nullo allo stesso tempo).

Ma:

  • Si rende il codice più difficile da leggere: "If blue is the sky..."
  • Se avete appena verificato che il vostro argomento non è nullo sulla riga precedente, allora è inutile.
  • Se si è dimenticato di eseguire il test per null e qualcuno ha un argomento nullo che non si aspettava, allora un NullPointerException non è necessariamente il peggior risultato possibile. Far finta che tutto sia OK e trasportare fino a quando fallisce in un secondo momento non è davvero un'alternativa migliore. Fallire veloce è buono

Personalmente non lo fanno pensare utilizzo di questa tecnica dovrebbe essere richiesto in tutti i casi. Penso che dovrebbe essere lasciato al giudizio del programmatore caso per caso. L'importante è assicurarti di aver gestito il caso nullo in modo appropriato e come lo fai dipende dalla situazione. Il controllo della corretta gestione dei valori nulli potrebbe far parte delle linee guida di verifica/revisione del codice.

+1

"Rende il codice più difficile da leggere:" Se il blu è il cielo ... "- altrimenti noto come condizioni yoda - http: // en.wikipedia.org/wiki/Yoda_conditions – chrismarx

10

È vero. Se variable è null nel tuo esempio,

variable.equals("xx"); 

lancerà una NPE perché non si può chiamare un metodo (equals) su un oggetto null. Ma

"xx".equals(variable); 

restituirà solo false senza errori.

+0

Ma 'variable' essendo' null' probabilmente dovrebbe essere un errore. –

+0

@ Tom: beh, forse. Ho incontrato situazioni in cui dovrebbe essere un errore e molte altre situazioni in cui non dovrebbe essere. Sono d'accordo con Mark Byers sul fatto che abbia senso valutarlo caso per caso. –

3

Questa è una tecnica comune utilizzata nei programmi Java (e C#). Il primo modulo evita l'eccezione del puntatore nullo perché il metodo .equals() viene chiamato sulla stringa costante "xx", che non è mai nullo. Una stringa non nulla rispetto a un valore null è falsa.

Se si sa che variable non sarà mai nullo (e il programma è errato in qualche altro modo se è mai nullo), quindi utilizzare variable.equals("xx") va bene.

4

In realtà, penso che la raccomandazione originale sia vera. Se si utilizza variable.equals("xx"), si otterrà un NullPointerException se variable è nullo. Mettendo la stringa costante sul lato sinistro si evita questa possibilità.

Sta a te decidere se questa difesa valga la pena di quello che molti considerano un linguaggio innaturale.

+1

Peronsalized Trovo molto difficile leggere la "versione Yoda", ma evita l'eccezione del puntatore nullo. L'alternativa è 's! = Null && s.equals ("xx")', che è più da digitare e richiede pochi extra nanosecondi per fare il confronto extra. – Jay

0

Se è necessario verificare per null, trovo questo più leggibile di if (variable != null && variable.equals("xx")). È più una questione di preferenze personali.

2

È vero che l'utilizzo di qualsiasi proprietà di un oggetto in questo modo consente di evitare l'NPE.

Ma è per questo che abbiamo Eccezioni, per gestire questo tipo di cose.

Forse se si utilizza "xx" .equals (variabile) non si saprebbe mai se il valore della variabile è nullo o semplicemente non è uguale a "xx". IMO è meglio sapere che stai ricevendo un valore nullo nella tua variabile, quindi puoi ridisegnarla, piuttosto che ignorarla.

0

Sei corretto sull'ordine del controllo - se la variabile è nullo, chiamare .equals sulla costante di stringa impedirà un NPE - ma non sono sicuro di considerarlo una buona idea; Personalmente lo chiamo "slop".

Lo slop è quando non si rileva una condizione anormale, ma in effetti si creano abitudini per evitare di essere scoperti. Passare intorno a un null come stringa per un lungo periodo di tempo porterà infine a errori che potrebbero essere oscuri e difficili da trovare.

La codifica per lo slop è l'opposto di "Fail fast fail hard".

L'utilizzo di un null come stringa può occasionalmente apportare un valore "Speciale", ma il fatto che si stia cercando di confrontarlo con qualcosa indica che la comprensione del sistema è incompleta (nella migliore delle ipotesi) - prima si trovare questo fatto, meglio è.

D'altra parte, rendere tutte le variabili finali per impostazione predefinita, utilizzando Generics e riducendo al minimo la visibilità di tutti gli oggetti/metodi sono abitudini che riducono lo slop.

0

Come nota a margine, ecco un modello di progettazione in cui questa raccomandazione codice potrebbe non fare alcuna differenza, dal momento che la stringa (cioè Optional<String>) non è mai nullo a causa della chiamata .isPresent() dal modello di progettazione:

Optional<String> gender = Optional.of("MALE"); 
if (gender.isPresent()) { 
    System.out.println("Value available."); 
} else { 
    System.out.println("Value not available."); 
} 
gender.ifPresent(g -> System.out.println("Consumer: equals: " + g.equals("whatever"))); 
Problemi correlati