Dlaczego tak się dzieje, jeśli stwierdzenie z przypisaniem i sprawdzeniem równości daje wynik fałszywy?

105

Jak działa instrukcja if w Javie , gdy ma przypisanie i sprawdzenie równości OR-d razem?

public static void test() {
    boolean test1 = true; 
    if (test1 = false || test1 == false) {
        System.out.println("TRUE");
    } else {
        System.out.println("FALSE");
    }       
}

Dlaczego to drukowanie jest FAŁSZEM?

RoHaN
źródło
1
Uruchom i sprawdź. Zobacz, jaka wartość logiczna jest wypisywana, jeśli przypiszesz fałsz i jeśli przypiszesz wartość true. Następnie przeczytaj, jak działa OR.
Pratik
2
Chciałbym powiedzieć, że ten kod w trybie debugowania daje wartość TRUE, aw trybie Running daje wartość FALSE ... Dlaczego tak jest ??? ... (
ustawiłem
test1=false, test1==falsejest false, false || falsejest, false or falsektóry jest false.
Jared Burrows
Wiem, że nie prosiłeś o radę, ale ponieważ poniższe odpowiedzi wskazują na problem z pierwszeństwem, oto kilka praktyk, które pomogły mi uniknąć kłopotów (kiedy trzymam się tych): (1) zawsze używaj nawiasów, jeśli nie w 100% pewne pierwszeństwo lub dla łatwiejszej czytelności, aby pomóc innym programistom. Nie zakładaj, że inni zapamiętają reguły pierwszeństwa dla wszystkich operatorów (2), należy zasadniczo unikać przypisań if, aby zmniejszyć nieporozumienia, z wyjątkiem bardzo prostych warunków warunkowych. Istnieje kilka typowych wyjątków (szczególnie w przypadku prostych kontroli we / wy, sieci itp.). Tylko moje dwa centy.
rimsky
ponieważtest1 = true
jono

Odpowiedzi:

189

Wyrażenie nie jest analizowane w sposób, w jaki myślisz. To nie jest

(test1=false) || (test1 == false)

w takim przypadku wynik byłby true, ale

test1 = (false || test1 == false)

Wartość false || test1 == falsewyrażenia jest obliczana jako pierwsza i tak jest false, ponieważ test1jest ustawiona na trueprzejście do obliczeń.

Powodem jest analizowany w ten sposób jest to, że pierwszeństwo z ||jest mniejsza niż ==operatora, ale większa niż priorytetu operatora przypisania =.

dasblinkenlight
źródło
2
+1 @RohanFernando, proszę również zauważyć, że jeśli dodasz nawiasy wokół przypisania w ten sposób: ((test1 = false) || test1 == false)ogólna wartość będzie true.
Arnon Zilca
1
Proszę napisać powód, dla którego tak się dzieje ... Czy wynika to z kolejności priorytetów operatorów?
kondu
3
@kondu To uczciwe pytanie uzupełniające, zredagowałem, dodając link do tabeli pierwszeństwa, która pokazuje, że ==jest powyżej ||, ale =jest poniżej ||.
dasblinkenlight
Ostatni akapit jest mylący w tym sensie, że aby zrozumieć, dlaczego wybrano drugie parsowanie, a nie pierwszy, wystarczy znać (łatwą do zapamiętania) regułę, że przypisanie ma niższy priorytet od dowolnego operatora nie-przypisania (tutaj ||). Względne pierwszeństwo ||i ==ma znaczenie tylko pokazać, że parsowanie jest nie tak jak w test1 = ((false || test1) == false), którym nie sądzę ktokolwiek oczekiwać (przy okazji, że względny priorytet, lub bardziej ogólnie, że ||, &&mają niższy priorytet niż stosunków, jest również łatwy do pamiętaj, ponieważ używany przez cały czas).
Marc van Leeuwen
1
@MarcvanLeeuwen Względne pierwszeństwo ||i ==vs ||oraz =wyjaśnia, dlaczego zachowuje się inaczej niż (powszechny) przypadek a == b || c == d.
Aaron Dufour
83

Zasadniczo jest to kwestia pierwszeństwa. Zakładasz, że Twój kod jest równoważny z:

if ((test1 = false) || (test1 == false))

... ale nie jest. W rzeczywistości jest to równoważne z:

if (test1 = (false || test1 == false))

... co jest równoważne z:

if (test1 = (false || false))

(bo test1ma truesię zacząć)

... co jest równoważne z:

if (test1 = false)

który przypisuje wartość falsedo test1, z wynikiem wyrażenia jest false.

Przydatną tabelę pierwszeństwa operatorów znajdziesz w samouczku Java dotyczącym operatorów .

Jon Skeet
źródło
2

proszę spojrzeć na pierwszeństwo operatorów

Expression test1 = false || test1 == falseoceni w następnym kroku.

KROK: 1- test1 = false || test1 == false // pierwszeństwo ==jest najwyższe

KROK: 2- test1 = false || false // Operator ||ma wyższy priorytet

KROK 3- test1 = false

KROK 4- false

Ponieważ wartość logiczna wyrażenia staje się fałszywa, więc instrukcja jest wykonywana.


źródło
-11

(test1 = false || test1 == false)zwraca fałsz, ponieważ oba są fałszywe. (test1 = false || test1 == true)to prawda, ponieważ jeden z nich jest prawdziwy

Legowisko
źródło
1
Całkowicie źle. Dlaczego miałbyś odpowiadać, podając tak niepoprawne informacje, kilka dni po tym, jak pytanie otrzymało dwie wysokiej jakości odpowiedzi, które opisują, co się dzieje?
l4mpi
5
Dwie tak niskiej jakości odpowiedzi nie zasługują na indywidualnie napisane uwagi. Zdajesz sobie sprawę, że twoja odpowiedź jest nonsensowna, prawda? Jeśli nie, przeczytaj uważnie dwie odpowiedzi Jona i migaj światłem.
l4mpi