- Làm cách nào để làm cho CaseInsensitiveString hoạt động giống như String để câu lệnh trên là ok (với và w / out mở rộng String)? Điều gì ở String khiến bạn có thể chuyển nó theo một nghĩa đen như vậy? Theo sự hiểu biết của tôi thì không có khái niệm "copy constructor" trong Java phải không?
Đã nói đủ ngay từ điểm đầu tiên. "Ba Lan" là một chuỗi ký tự và không thể được gán cho lớp CaseInsentiviveString.
Bây giờ về điểm thứ hai
Mặc dù bạn không thể tạo các ký tự mới, nhưng bạn có thể làm theo mục đầu tiên của cuốn sách đó để có cách tiếp cận "tương tự" để các câu sau là đúng:
CaseInsensitiveString cis5 = CaseInsensitiveString.valueOf("sOmEtHiNg");
CaseInsensitiveString cis6 = CaseInsensitiveString.valueOf("SoMeThInG");
assert cis5 == cis6;
assert cis5.equals(cis6);
Đây là mã.
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();
}
// Kiểm tra lớp bằng từ khóa "khẳng định"
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>
Đó là, tạo một nhóm bên trong các đối tượng CaseInsensitiveString và trả về cá thể tương ứng từ đó.
Bằng cách này, toán tử "==" trả về true cho hai tham chiếu đối tượng đại diện cho cùng một giá trị .
Điều này rất hữu ích khi các đối tượng tương tự được sử dụng rất thường xuyên và việc tạo ra chi phí đắt đỏ.
Tài liệu lớp chuỗi nói rằng lớp sử dụng một nhóm bên trong
Lớp chưa hoàn chỉnh, một số vấn đề thú vị phát sinh khi chúng ta cố gắng tìm hiểu nội dung của đối tượng khi triển khai giao diện CharSequence, nhưng mã này đủ tốt để cho thấy mục đó trong Sách có thể được áp dụng như thế nào.
Điều quan trọng cần lưu ý là bằng cách sử dụng đối tượng InternalPool , các tham chiếu không được giải phóng và do đó không được thu gom rác và điều đó có thể trở thành một vấn đề nếu nhiều đối tượng được tạo.
Nó hoạt động cho lớp String vì nó được sử dụng chuyên sâu và nhóm chỉ được tạo thành từ đối tượng "interned".
Nó cũng hoạt động tốt cho lớp Boolean, vì chỉ có hai giá trị có thể.
Và cuối cùng đó cũng là lý do tại sao valueOf (int) trong lớp Integer bị giới hạn từ -128 đến 127 giá trị int.