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?


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 =.


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 .


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.


-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


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
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.