- Come faccio a far sì che CaseInsensitiveString si comporti come String in modo che l'istruzione sopra sia ok (con e senza estensione String)? Di cosa si tratta String che rende giusto essere in grado di passarlo letteralmente come quello? Dalla mia comprensione non esiste il concetto di "costruttore di copia" in Java, giusto?
È stato detto abbastanza dal primo punto. "Polish" è una stringa letterale e non può essere assegnata alla classe CaseInsentiviveString.
Ora sul secondo punto
Sebbene non sia possibile creare nuovi valori letterali, è possibile seguire il primo elemento di quel libro per un approccio "simile", quindi le seguenti affermazioni sono vere:
CaseInsensitiveString cis5 = CaseInsensitiveString.valueOf("sOmEtHiNg");
CaseInsensitiveString cis6 = CaseInsensitiveString.valueOf("SoMeThInG");
assert cis5 == cis6;
assert cis5.equals(cis6);
Ecco il codice.
C:\oreyes\samples\java\insensitive>type CaseInsensitiveString.java
import java.util.Map;
import java.util.HashMap;
public final class CaseInsensitiveString {
private static final Map<String,CaseInsensitiveString> innerPool
= new HashMap<String,CaseInsensitiveString>();
private final String s;
public static CaseInsensitiveString valueOf( String s ) {
if ( s == null ) {
return null;
}
String value = s.toLowerCase();
if ( !CaseInsensitiveString.innerPool.containsKey( value ) ) {
CaseInsensitiveString.innerPool.put( value , new CaseInsensitiveString( value ) );
}
return CaseInsensitiveString.innerPool.get( value );
}
public CaseInsensitiveString(String s){
if (s == null) {
throw new NullPointerException();
}
this.s = s.toLowerCase();
}
public boolean equals( Object other ) {
if ( other instanceof CaseInsensitiveString ) {
CaseInsensitiveString otherInstance = ( CaseInsensitiveString ) other;
return this.s.equals( otherInstance.s );
}
return false;
}
public int hashCode(){
return this.s.hashCode();
}
// Verifica la classe utilizzando la parola chiave "assert"
public static void main( String [] args ) {
CaseInsensitiveString cis1 = new CaseInsensitiveString("Polish");
CaseInsensitiveString cis2 = new CaseInsensitiveString("Polish");
assert cis1 != cis2;
assert cis1.equals(cis2);
CaseInsensitiveString cis3 = CaseInsensitiveString.valueOf("Polish");
CaseInsensitiveString cis4 = CaseInsensitiveString.valueOf("Polish");
assert cis3 == cis4;
assert cis3.equals(cis4);
CaseInsensitiveString cis5 = CaseInsensitiveString.valueOf("sOmEtHiNg");
CaseInsensitiveString cis6 = CaseInsensitiveString.valueOf("SoMeThInG");
assert cis5 == cis6;
assert cis5.equals(cis6);
CaseInsensitiveString cis7 = CaseInsensitiveString.valueOf("SomethinG");
CaseInsensitiveString cis8 = CaseInsensitiveString.valueOf("someThing");
assert cis8 == cis5 && cis7 == cis6;
assert cis7.equals(cis5) && cis6.equals(cis8);
}
}
C:\oreyes\samples\java\insensitive>javac CaseInsensitiveString.java
C:\oreyes\samples\java\insensitive>java -ea CaseInsensitiveString
C:\oreyes\samples\java\insensitive>
Ovvero, creare un pool interno di oggetti CaseInsensitiveString e restituire l'istanza corrispondente da lì.
In questo modo l'operatore "==" restituisce true per due riferimenti a oggetti che rappresentano lo stesso valore .
Ciò è utile quando oggetti simili vengono utilizzati molto frequentemente e il costo di creazione è costoso.
La documentazione della classe stringa afferma che la classe utilizza un pool interno
La classe non è completa, sorgono alcuni problemi interessanti quando proviamo a esplorare i contenuti dell'oggetto durante l'implementazione dell'interfaccia CharSequence, ma questo codice è abbastanza buono per mostrare come quell'elemento nel Libro potrebbe essere applicato.
È importante notare che utilizzando internalPool oggetto , i riferimenti non vengono rilasciati e quindi non possono essere raccolti in modo indesiderato, e questo può diventare un problema se vengono creati molti oggetti.
Funziona per la classe String perché viene utilizzata in modo intensivo e il pool è costituito solo da oggetti "internati".
Funziona bene anche per la classe booleana, perché ci sono solo due valori possibili.
E infine questo è anche il motivo per cui valueOf (int) nella classe Integer è limitato da -128 a 127 valori int.