Son Java ilan eden == ile karşılaştırma dizeleri
Java dizeleri hakkında basit bir sorum var. Basit aşağıdaki kod kesimi sadece iki dizeleri birleştirir ve sonra ==
ile karşılaştırır.
String str1="str";
String str2="ing";
String concat=str1 str2;
System.out.println(concat=="string");
7* *karşılaştırma ifadesi false
olarak açık (equals()
==
arasındaki farkı anlıyorum) verir.
Bu iki dize final
gibi ilan edilir
final String str1="str";
final String str2="ing";
String concat=str1 str2;
System.out.println(concat=="string");
Karşılaştırma bu durumda concat=="string"
ifade true
döndürür. Neden final
bir fark yaratır mı? Stajyer havuzu ya da sadece yanıltılmış oluyorum ile bir ilgisi var mı?
CEVAP
String
bildirdiğinizde (kideğişmezdeğişken olarak final
ve başlatmak bir derleme zamanı sabiti ifadesi, o da olur bir derleme zamanı sabiti ve değeri derleyici tarafından inlined nerede kullanılır. Bu yüzden, değerleri satır içi uygulaması sonra ikinci kod örneği, bir dize birleştirme için derleyici tarafından tercüme edilmiştir:
String concat = "str" "ing"; // which then becomes `String concat = "string";`
zaman göre "string"
dize hazır olduğundan true
, verecektirstaj yaptım.
JLS §4.12.4 - final
Variables:
İlkel tip veya türde bir değişken
final
ile başlatılmış olanString
, bir derleme zamanı sabiti (§15.28), olarak adlandırılırsürekli değişken.
JLS §15.28 - Constant Expression: da
< / ^ hr .Derleme zamanı
String
her zaman verilen bir tür sabit ifade< . em^"" . staj benzersiz örneklerini paylaşmak için, bu yöntemi kullanarak 31**.
Bu String
değişkenler final
burada ilk kod örneği, durum böyle değil. Yani, onlar bir derleme zamanı sabiti ifadeleri. Birleştirme işlemi oraya kadar zamanı, böylece String
yeni bir nesne yaratılmasına yol açan gecikecek. Her iki kodları byte kod karşılaştırarak bu doğrulayabilirsiniz.
İlk kod örneği(non-final
sürüm)aşağıdaki bayt koduna derlenir:
Code:
0: ldc #2; //String str
2: astore_1
3: ldc #3; //String ing
5: astore_2
6: new #4; //class java/lang/StringBuilder
9: dup
10: invokespecial #5; //Method java/lang/StringBuilder."<init>":()V
13: aload_1
14: invokevirtual #6; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
17: aload_2
18: invokevirtual #6; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
21: invokevirtual #7; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
24: astore_3
25: getstatic #8; //Field java/lang/System.out:Ljava/io/PrintStream;
28: aload_3
29: ldc #9; //String string
31: if_acmpne 38
34: iconst_1
35: goto 39
38: iconst_0
39: invokevirtual #10; //Method java/io/PrintStream.println:(Z)V
42: return
Açıkça iki ayrı değişkenleri str
ing
saklama ve StringBuilder
birleştirme işlemi gerçekleştirmek için kullanıyor.
Oysa, ikinci kod örneği(final
sürüm)bu gibi görünüyor:
Code:
0: ldc #2; //String string
2: astore_3
3: getstatic #3; //Field java/lang/System.out:Ljava/io/PrintStream;
6: aload_3
7: ldc #2; //String string
9: if_acmpne 16
12: iconst_1
13: goto 17
16: iconst_0
17: invokevirtual #4; //Method java/io/PrintStream.println:(Z)V
20: return
Doğrudan adımda ldc
operasyon 0
tarafından yüklenen Dize derleme zamanında 23**, oluşturmak için son değişken inlines. İkinci dize adımda ldc
operasyon 7
tarafından yüklenir. Zamanında String
yeni nesnelerin oluşturulması ile ilgili değil. Dize zaten derleme zamanında bilinen ve staj yaptım.
Referans karşılaştırma (==) bazı dizel...
Dizi Java mı ilan edeceğiz?...
Karşılaştırma Java numaralama üyeleri:...
Neden Python karşılaştırma dizeleri ku...
Java Dize dizisi için ArrayList içeren...