Dziwne zachowanie == dla stringów

Dziwne zachowanie == dla stringów
0

Dlaczego wyświetla się equal mimo, że teoretycznie te obiekty są różne i powinniśmy użyć metody equals a nie ==?

Kopiuj
public class Main {
    public static void main(String[] args) {
        String[] tab = {"1","1","3","4"};

        if(tab[0]==tab[1])
            System.out.println("equal");
    }
}

Czy to jest optymalizacja kompilatora która do dwóch pierwszych referencji przypisuje ten sam obiekt?(nie powinno mieć to skutków ubocznych skoro stringi są immutable)

S9
Polecam pouczyć się w przyszłości o Java Memory Model ;]
Wibowit
Java Memory Model raczej nie zajmuje się takimi rzeczami (choć mogę się mylić)
Shalom
  • Rejestracja:ponad 21 lat
  • Ostatnio:około 3 lata
  • Lokalizacja:Space: the final frontier
  • Postów:26433
1

Czy to jest optymalizacja kompilatora która do dwóch pierwszych referencji przypisuje ten sam obiekt?(nie powinno mieć to skutków ubocznych skoro stringi są immutable)

Nie, to optymalizacja na poziomie samego języka, nie kompilatora. Tworząc stringa w ten sposób, bez new, korzystasz z internal cache:

Moreover, a string literal always refers to the same instance of class String. This is because string literals - or, more generally, strings that are the values of constant expressions (§15.28) - are "interned" so as to share unique instances, using the method String.intern.

https://docs.oracle.com/javase/specs/jls/se7/html/jls-3.html#jls-3.10.5


"Nie brookliński most, ale przemienić w jasny, nowy dzień najsmutniejszą noc - to jest dopiero coś!"
edytowany 1x, ostatnio: Shalom
jarekczek
  • Rejestracja:prawie 8 lat
  • Ostatnio:ponad 4 lata
  • Lokalizacja:Siemianowice Śląskie
  • Postów:500
0
Kopiuj
|  Welcome to JShell -- Version 9.0.4
|  For an introduction type: /help intro

jshell> String a = "1";
a ==> "1"

jshell> a += "2";
$2 ==> "12"

jshell> a == "12"
$3 ==> false

jshell> a.intern() == "12"
$4 ==> true

Przeważnie ignoruję niezarejestrowanych użytkowników.
Koziołek
Moderator
  • Rejestracja:około 18 lat
  • Ostatnio:7 dni
  • Lokalizacja:Stacktrace
  • Postów:6822
0

I jeszcze jeden mały myk. Od czasów Javy 8 mamy mechanizm deduplikacji Stringów. Działa toto z G1GC i wymaga flag -XX:+UseG1GC -X:+UseStringDeduplication -XX:+PrintStringDeduplicationStatistics (obecnie G1GC jest domyślny więc już bez pierwszej, a ostatnia jest "ciekawostkowa"). Zatem jak komuś zależy na pamięci to warto o tym pamiętać.


Sięgam tam, gdzie wzrok nie sięga… a tam NullPointerException
Wibowit
ZTCW to to deduplikuje tablice charów pod Stringami, ale nie same obiekty klasy String.

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.