- 我如何使 CaseInsensitiveString 表现得像 String 一样,所以上面的语句是可以的(有和没有扩展 String)?是什么让 String 可以像这样传递文字?据我了解,Java 中没有“复制构造函数”的概念吗?
从第一点就说得够多了。 "Polish" 是字符串文字,不能分配给 CaseInsentiviveString 类。
关于第二点
虽然您不能创建新的文字,但您可以按照该书的第一项“类似”方法,因此以下陈述是正确的:
// Lets test the insensitiveness
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;
// Effective Java Item 1: Consider providing static factory methods instead of constructors
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 );
}
// Class constructor: This creates a new instance each time it is invoked.
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 ) {
// Creating two different objects as in new String("Polish") == new String("Polish") is false
CaseInsensitiveString cis1 = new CaseInsensitiveString("Polish");
CaseInsensitiveString cis2 = new CaseInsensitiveString("Polish");
// references cis1 and cis2 points to differents objects.
// so the following is true
assert cis1 != cis2; // Yes they're different
assert cis1.equals(cis2); // Yes they're equals thanks to the equals method
// Now let's try the valueOf idiom
CaseInsensitiveString cis3 = CaseInsensitiveString.valueOf("Polish");
CaseInsensitiveString cis4 = CaseInsensitiveString.valueOf("Polish");
// References cis3 and cis4 points to same object.
// so the following is true
assert cis3 == cis4; // Yes they point to the same object
assert cis3.equals(cis4); // and still equals.
// Lets test the insensitiveness
CaseInsensitiveString cis5 = CaseInsensitiveString.valueOf("sOmEtHiNg");
CaseInsensitiveString cis6 = CaseInsensitiveString.valueOf("SoMeThInG");
assert cis5 == cis6;
assert cis5.equals(cis6);
// Futhermore
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 对象的内部池,并从那里返回相应的实例。
这样,“==”运算符为代表相同值的两个对象引用返回true。
当相似的对象被频繁使用并且创建成本昂贵时,这很有用。
字符串类文档指出该类使用an internal pool
类不完整,当我们尝试在实现 CharSequence 接口时遍历对象的内容时会出现一些有趣的问题,但是这段代码足以说明如何应用 Book 中的项目。
重要的是要注意,通过使用 internalPool 对象,引用不会被释放,因此不会被垃圾回收,如果创建了很多对象,这可能会成为一个问题。
它适用于 String 类,因为它被密集使用并且池仅由“interned”对象构成。
它也适用于布尔类,因为只有两个可能的值。
最后,这也是 Integer 类中的 valueOf(int) 限制为 -128 到 127 个 int 值的原因。