-CaseInsensitiveStringをStringのように動作させて、上記のステートメントで問題がないようにするにはどうすればよいですか(Stringを拡張する場合としない場合)。そのようなリテラルを渡すことができるようにするのは、Stringについて何ですか?私の理解では、Javaには「コピーコンストラクタ」の概念はありませんよね?
最初の点から十分に言われています。「ポーランド語」は文字列リテラルであり、CaseInsentiviveStringクラスに割り当てることはできません。
さて、2点目について
新しいリテラルを作成することはできませんが、その本の最初の項目に従って「同様の」アプローチをとることができるため、次のステートメントが当てはまります。
CaseInsensitiveString cis5 = CaseInsensitiveString.valueOf("sOmEtHiNg");
CaseInsensitiveString cis6 = CaseInsensitiveString.valueOf("SoMeThInG");
assert cis5 == cis6;
assert cis5.equals(cis6);
これがコードです。
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();
}
//「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>
つまり、CaseInsensitiveStringオブジェクトの内部プールを作成し、そこから対応するインスタンスを返します。
このように、「==」演算子は、同じ値を表す2つのオブジェクト参照に対してtrueを返します。
これは、同様のオブジェクトが非常に頻繁に使用され、作成コストが高い場合に役立ちます。
文字列クラスのドキュメントには、クラスが内部プールを使用すると記載されています
クラスは完全ではありません。CharSequenceインターフェイスの実装時にオブジェクトのコンテンツをウォークしようとすると、いくつかの興味深い問題が発生しますが、このコードは、ブック内のそのアイテムをどのように適用できるかを示すのに十分です。
internalPoolオブジェクトを使用すると、参照が解放されないため、ガベージコレクターになりません。これは、多数のオブジェクトが作成される場合に問題になる可能性があることに注意してください。
集中的に使用され、プールは「インターン」オブジェクトのみで構成されているため、Stringクラスで機能します。
可能な値は2つしかないため、ブールクラスでもうまく機能します。
そして最後に、それが整数クラスのvalueOf(int)が-128から127のint値に制限されている理由でもあります。