Вы путаете сложность времени компиляции со сложностью времени выполнения.
Когда класс загружен, да, он выполняет поиск, чтобы увидеть, существует ли каждый литерал (хотя я предполагаю, что он использует хеш-карту для O (1) поиск вместо вашего предложения).
Когда код выполняется, он имеет ссылку на строку в памяти, поэтому нет никаких дополнительных затрат, кроме не-литерального.
Так что да,литералы интернированы.Согласно Javadoc для String,
Пул строк, изначально пустой, поддерживается в частном порядке классом String.
Вы можете вызвать intern()
для String, чтобы добавить его в этот пул.Логически следует, что если a.equals(b)
, то a.intern() == b.intern()
, поскольку .intern()
гарантирует возврат из уникального пула.
Пример:
class InternTest {
// assuming InternTest is the only class, internPool.size = 0
String x = "ABC"; // interned at class load, internPool.size = 1
String y = "DEF"; // interned at class load, internPool.size = 2
String z = "ABC"; // interned at class load, but match found - size = 2 still
void foo() {
// random int is just a mechanism to get something that I know won't
// be interned at loadtime - could have loaded from file or database too
int i = (new java.util.Random()).nextInt(1000) + 100;
int j = i;
String s = String.valueOf(i); // not yet interned, size = 2 still
String t = String.valueOf(j); // not yet interned, size = 2 still
String sIntern = s.intern(); // manually interned, size = 3 now
String tIntern = t.intern(); // manually interned, match found, size = 3 still
System.out.println("equals: " + (s.equals(t))); // should be true
System.out.println("== raw: " + (s == t)); // should be false, different variables
System.out.println("== int: " + (sIntern == tIntern)); // should be true, from unique pool
System.out.println("x and z: " + (x == z)); // should be true, interned at class load
}
public static void main(String[] args) {
(new InternTest()).foo();
}
}
Результаты при запуске:
C:\Documents and Settings\glowcoder\My Documents>java InternTest
equals: true
== raw: false
== int: true
x and z: true
Я должен отметить, что предположение никогда не будет верным.Сам по себе язык Java имеет много String
, которые были бы интернированы до того, как наши String
когда-либо увидят свет.Однако, предполагая, что все загружается последовательно, если вы рассматриваете только интернализируемую дельту строк, и не допускаете столкновений с существующими интернами (мы все знаем, что интерны могут быть суетливыми и полными драмы, верно? snicker ) тогдачисла действительно указывают дельту размера пула строк.