V obou pripadech se IMHO nevygeneruje stejny byte kod.
V prvnim pripade: String a = "abc";
se pouzije objekt String z poolu String konstant a novy objekt se dynamicky nevytvari (jen se priradi odkaz na konstantu).
Ve druhem pripade:
String b = new String("abc");
se (zbytecne) vytvari novy objekt (kopie konstanty "abc"), zbytecne vetsi rezie za behu.
Není to pravda - používaní literálů a konstrukce new String("asd") vede k jiným výsledkům a i v chování.
public class Pokus {
public static void main(String[] args) {
String a = "asdf";
if (a == new Hu().x) {
System.out.println("true a hotovo");
}
}
}
class Hu {
String x = "asdf";
}
Toto by v případě použití konstrukce new mělo jiný výsledek.
Zajimava vec,
jeste zajimavejsi me prijde fakt, ze nasledujici kousek taky projde:
public class Pokus {
static String b = "a" + "s" + "d" + "f";
public static void main(String[] args) {
String a = "asdf";
if (a == b) {
System.out.println("true a hotovo");
}
}
}
Zajimalo by me, jestli je toto chovani ve specifikaci, nebo se lisi v ruznych implementacich Javy.
Mate v tom celkem chaos ... se mi zda
String a = "ads";
a
String b = new String("ads");
je UPLNE to same. U obou se vytvori novy objekt String a je nainicializovan na danou hodnotu. String se ale pri porovnavani chova trochu "podivne" a neporovnava se rovnost objectu, ale rovnost obsahu.
A co vice, kdyz se podivate do byto codu, co vznikne pri
String a = "a" + "b" + "c";
tak je to celkem zbesile, na kazde string, literal, se vytvori novy StringBuffer object a k nemu se pak "appendne" dalsi a dalsi a na vysledek se udela new String(strBuffer.toString());
K rozhodnutí, zda překládá java výrazy
String a = "abcdefg"
a
String a = new String("abcdefg")
jsem si vytvořil dva programy:
public class Test1 {
public static void main (String [] args) {
String a = "abcdefg";
}
}
a
public class Test2 {
public static void main (String [] args) {
String a = new String ("abcdefg");
}
}
První má po přeložení (tj. soubor Test1.class) 275B, druhý (soubor Test2.class) má 338B. Pomocí programu javap lze převést bytecode do čitelného tvaru, metoda main v prvním programu vypadá následovně:
Method void main(java.lang.String[])
0 ldc #2 <String "abcdefg">
2 astore_1
3 return
Metoda main v druhém programu vypadá následovně:
Method void main(java.lang.String[])
0 new #2 <Class java.lang.String>
3 dup
4 ldc #3 <String "abcdefg">
6 invokespecial #4 <Method java.lang.String
(java.lang.String)>
9 astore_1
10 return
Testy jsem prováděl pod Windows XP s JDK 1.4.0
Luboš Pavlíček
P.S. Též jsem si myslel, že to přeloží stejně. Z tohoto příkladu nevyplývá, jak to přeloží jiné překladače (jikes, SDK od IBM, ...).