- Как заставить CaseInsensitiveString вести себя как String, поэтому вышеприведенный оператор в порядке (с и без расширения строки)? Что это такое в String, что делает его достаточно, чтобы просто передать его буквально? Насколько я понимаю, в Java нет концепции «конструктор копий»?
Достаточно было сказано с первого пункта. «Польский» является строковым литералом и не может быть назначен классу 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();
}
// Тестирование класса с использованием «ключевого слова» утверждают,
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, и вернуть corrensponding экземпляр оттуда.
Таким образом, «==» оператор возвращает верно для двух ссылок на объекты, представляющие одинаковое значение.
Это полезно, когда подобные объекты используются очень часто, а стоимость стоит дорого.
документация класс
строка гласит, что класс использует an internal pool
Класс не является полным, некоторые интересные вопросы возникают, когда мы пытаемся ходить содержимое объекта при реализации интерфейса CharSequence, но этот код достаточно хорошо чтобы показать, как этот пункт в Книге может быть применен.
Важно отметить, что с помощью объекта internalPool internalPool ссылки не освобождаются и, следовательно, не собираются в мусор, и это может стать проблемой при создании большого количества объектов.
Он работает для класса String, потому что он используется интенсивно, а пул состоит только из «интернированного» объекта.
Он хорошо подходит для булевого класса, потому что есть только два возможных значения.
И, наконец, это также причина, почему valueOf(int) в классе Integer ограничен значениями от -128 до 127 int.
Строка str1 = "Foo"; String str2 = "foo"; Оба str1 и str2 принадлежат к одному и тому же объекту String, «foo», b'coz для Java управляет Strings в StringPool, так что новая переменная относится к той же String, она не создает другого, а назначает тот же самый алертад, присутствующий в StringPool. Но когда мы это делаем: String str1 = new String ("foo"); String str2 = new String ("foo"); Здесь str1 и str2 принадлежат к различным объектам, b'coz new String() принудительно создает новый объект String. – Akash5288 2013-12-27 08:23:46