Ten fragment koduWyjaśnienie odniesienia i metody wykonania StringBuilder celu
StringBuilder b1=new StringBuilder("hello");
b1.append(b1.append("!"));
System.out.println("b1 = "+b1);
wypisze
b1 = hello!hello!
ponieważ wewnętrzna append
wykonywany jest pierwszy i modyfikuje obiektu b1
; następnie oceniana jest zewnętrzna wartość b1
(jest ona teraz równa hello!
) i dołączany jest do niej ten sam ciąg. Więc
- wewnętrzny wyrażenie jest wykonywane
- oryginalny obiekt zostanie zmodyfikowany
- ekspresja zewnętrzna wykonywana jest na zmodyfikowanej obiektu
Ale teraz, dlaczego ten kod rzucać NullPointerException
?
StringBuilder s1=null;
StringBuilder s2=new StringBuilder("world");
try{s1.append(s1=s2.append("!"));}
catch(Exception e){System.out.println(e);}
System.out.println("s1 = "+s1+"\ns2 = "+s2+"\n");
i drukuje
java.lang.NullPointerException
s1 = world!
s2 = world!
Spodziewałem odniesienie s1
być wskazując na obiekt odwołuje s2
przed zewnętrzna append
zostanie wykonany.
W pewnym sensie przypisanie b1.append("!");
wpływa na "zewnętrzny" b1
, ale s1=s2.append("!")
nie. Wiem, że wynika to z faktu, że w pierwszym przypadku modyfikuję obiekt, podczas gdy w drugim modyfikuję odwołanie, ale ... w jakiej kolejności wartości/referencje/metody są oceniane i wykonywane?
Edit
samo dzieje się z tablicami:
int[] y = { 0, 0, 0 };
try {y[y[0] = 2] = 4;}
catch (Exception e) {System.out.println(e);}
System.out.println("y = "+Arrays.toString(y)+"\n");
wydruków
y = [2, 0, 4]
podczas
int[] x1 = null;
int[] x2 = { 1, 2, 3 };
try {x1[(x1=x2)[0]] = 0;}
catch (Exception e) {System.out.println(e);}
System.out.println("x1 = "+Arrays.toString(x1)+"\nx2 = "+Arrays.toString(x2));
drukuje
Ok, ale tutaj "b1.append (b1.append ("! "));" Spodziewałbym się, że zewnętrzny "b1" zostanie oceniony jako równy "hello", a następnie wykona wewnętrzne polecenie i spowoduje "hellohello! ' –
@LuigiCortese' b1.append ("!"); 'Nie zwraca nowej instancji. Więc odniesienie jest wciąż takie samo. –
Uhm ... i dlaczego robi różnicę ...? Mam na myśli, jeśli reguła jest taka, że * odniesienie zewnętrzne jest oceniane przed wyrażeniem wewnętrznym *, nie rozumiem, dlaczego nie mogłem mieć 'hellohello!'. Dość zdezorientowany! –