- ฉันจะทำให้ CaseInsensitiveString ทำงานเหมือน String ได้อย่างไรดังนั้นข้อความข้างต้นจึงใช้ได้ (มีและ w / out ขยาย String) มันเกี่ยวอะไรกับ String ที่ทำให้มันสามารถส่งผ่านตัวอักษรแบบนั้นได้? จากความเข้าใจของฉันไม่มีแนวคิด "copy constructor" ใน Java ใช่ไหม
ได้รับการกล่าวถึงตั้งแต่จุดแรก "Polish" เป็นสตริงลิเทอรัลและไม่สามารถกำหนดให้กับคลาส CaseInsentiviveString
ตอนนี้เกี่ยวกับจุดที่สอง
แม้ว่าคุณจะไม่สามารถสร้างตัวอักษรใหม่ได้ แต่คุณสามารถทำตามรายการแรกของหนังสือเล่มนั้นสำหรับแนวทางที่ "คล้ายกัน" ดังนั้นข้อความต่อไปนี้จึงเป็นจริง:
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 และส่งคืนอินสแตนซ์ corrensponding จากที่นั่น
วิธีนี้ "==" ผู้ประกอบการผลตอบแทนที่แท้จริงสำหรับสองวัตถุอ้างอิงที่เป็นตัวแทนของค่าเดียวกัน
สิ่งนี้มีประโยชน์เมื่อมีการใช้วัตถุที่คล้ายกันบ่อยมากและต้นทุนการสร้างมีราคาแพง
เอกสารประกอบคลาสสตริงระบุว่าคลาสใช้พูลภายใน
ชั้นเรียนยังไม่สมบูรณ์ปัญหาที่น่าสนใจบางอย่างเกิดขึ้นเมื่อเราพยายามเดินเนื้อหาของวัตถุในการใช้งานอินเทอร์เฟซ CharSequence แต่รหัสนี้ดีพอที่จะแสดงให้เห็นว่าสามารถนำรายการนั้นไปใช้อย่างไรในหนังสือ
สิ่งสำคัญคือต้องสังเกตว่าการใช้ออบเจ็กต์internalPoolโดยการใช้การอ้างอิงจะไม่ถูกปล่อยออกมาดังนั้นจึงไม่ใช่ขยะที่รวบรวมได้และอาจกลายเป็นปัญหาหากมีการสร้างวัตถุจำนวนมาก
ใช้งานได้กับคลาส String เนื่องจากมีการใช้งานอย่างเข้มข้นและพูลประกอบด้วยอ็อบเจ็กต์ "interned" เท่านั้น
มันทำงานได้ดีสำหรับคลาสบูลีนเช่นกันเนื่องจากมีเพียงสองค่าที่เป็นไปได้
และในที่สุดนั่นก็เป็นเหตุผลว่าทำไมvalueOf (int)ในคลาสจำนวนเต็มจึงถูก จำกัด ไว้ที่ -128 ถึง 127 ค่า int