s1 == ""
non è affidabile come test parità riferimento si oppone uguaglianza (e String non è strettamente canonica).
s1.equals("")
è migliore ma può risentire delle eccezioni del puntatore nullo. Meglio ancora:
"".equals(s1)
Nessuna eccezione di puntatore nullo.
MODIFICA: Ok, è stato chiesto il punto canonical form. Questo articolo lo definisce come:
Supponiamo di avere un set S di oggetti, con una relazione di equivalenza. Una forma canonica è data designando alcuni oggetti di S di essere "in canonica forma", tale che ogni oggetto in esame equivale esattamente un oggetto in forma canonica.
Per dare un esempio pratico: prendere l'insieme di numeri razionali (o "frazioni" sono comunemente chiamati). Un numero razionale consiste in un numeratore e un denomoinator (divisore), che sono entrambi numeri interi. Questi numeri razionali sono equivalenti:
3/2, 6/4, 24/16
nubmers razionali sono tipicamente scritti in modo tale che il MCD (massimo comune divisore) è 1. Quindi, tutti loro sarà semplificata 3/2. 3/2 può essere visualizzato come il modulo canonico di questo insieme di numeri razionali.
Quindi cosa significa programmare quando viene utilizzato il termine "forma canonica"? Può significare un paio di cose. Prendiamo ad esempio questa classe immaginaria:
public class MyInt {
private final int number;
public MyInt(int number) { this.number = number; }
public int hashCode() { return number; }
}
Il codice hash della classe MyInt è una forma canonica di quella classe perché per l'insieme di tutte le istanze di MyInt, si può prendere due elementi qualsiasi M1 e M2 e saranno obbedire la seguente relazione:
m1.equals(m2) == (m1.hashCode() == m2.hashCode())
Questa relazione è l'essenza della forma canonica. Un modo più comune questo affiora è quando si utilizzano metodi di fabbrica su classi come:
public class MyClass {
private MyClass() { }
public MyClass getInstance(...) { ... }
}
istanze non possono essere istanziati direttamente poiché il costruttore è privato. Questo è solo un metodo di fabbrica. Quello che un metodo factory ti permette di fare è cose come:
- Restituire sempre la stessa istanza (sottratto singleton);
- Basta creare una nuova inattanza con ogni chiamata;
- Restituzione di oggetti in forma canonica (maggiori dettagli in un secondo); oppure
- qualunque cosa ti piaccia.
Fondamentalmente gli abstract metodo fabbrica oggetto la creazione e personalmente penso che sarebbe una caratteristica del linguaggio interessante per costringere tutti i costruttori di essere privato di far rispettare l'uso di questo modello, ma sto divagando.
Che cosa si può fare con questo metodo factory è cache di istanze che si crea tale che per ogni due istanze S1 e S2 obbediscono il seguente test:
(s1 == s2) == s1.equals(s2)
Quindi, quando dico String non è strettamente canonica vuol dire che:
String s1 = "blah";
String s2 = "blah";
System.out.println(s1 == s2); // true
ma come altri hanno poitned out è possibile modificare questo utilizzando:
String s3 = new String("blah");
e possibilmente:
String s4 = String.intern("blah");
Quindi non si può fare affidamento sulla parità di riferimento completamente, quindi non si dovrebbe fare affidamento su di esso a tutti.
Come un avvertimento al modello sopra, devo sottolineare che la creazione di oggetti di controllo con costruttori privati e metodi di fabbrica non garantisce l'uguaglianza di riferimento significa uguaglianza di oggetto a causa della serializzazione. La serializzazione aggira il normale meccanismo di creazione dell'oggetto. Josh Bloch tratta questo argomento in Effective Java (originariamente nella prima edizione quando parlava del pattern enum tipizzato che in seguito divenne un linguaggio in Java 5) e puoi aggirare il problema sovraccaricando il metodo readResolve() (privato). Ma è difficile. Anche i caricatori di classe influenzeranno il problema.
In ogni caso, questa è la forma canonica.
Non sta comparando la lunghezza migliore? Ritengo che la comparazione della lunghezza sia più ottimizzata della comparazione delle stringhe – Ravisha
@Ravisha Internally, ['String.java''s] (http://www.docjar.com/html/api/java/lang/String.java.html)' il metodo equals' ha diverse ottimizzazioni: ** 1: ** Reference '==' confronto, ** 2: ** 'instanceof String' check prima del casting, e ** 3: ** confronto del valore della lunghezza prima di confrontare finalmente il personaggio delle stringhe per carattere. Quindi, per rispondere alla tua domanda, sì, il confronto della lunghezza è efficiente, ma il tuo codice dovrebbe fare affidamento su String.equals e non reinventare nessuna delle sue ruote. –
@Patrick M. Se l'intenzione qui è di verificare la stringa vuota, preferisco confrontare la lunghezza. Piuttosto che un confronto. – Ravisha