Apakah operator Java & = berlaku & atau &&?

139

Asumsi

boolean a = false;

Saya bertanya-tanya apakah melakukan:

a &= b; 

setara dengan

a = a && b; //logical AND, a is false hence b is not evaluated.

atau di sisi lain artinya

a = a & b; //Bitwise AND. Both a and b are evaluated.
pakore
sumber

Jawaban:

146

Dari Spesifikasi Bahasa Jawa - 15.26.2 Operator Penugasan Majemuk .

Ekspresi penugasan majemuk bentuk E1 op= E2setara dengan E1 = (T)((E1) op (E2)), di mana Tjenis E1, kecuali yang E1dievaluasi hanya sekali.

Jadi a &= b;setara dengan a = a & b;.

(Dalam beberapa penggunaan, tipe-casting membuat perbedaan pada hasilnya, tetapi dalam tipe ini bharus booleandan tipe-cast tidak melakukan apa-apa.)

Dan, sebagai catatan, a &&= b;Java tidak valid. Tidak ada &&=operator.


Dalam praktiknya, ada sedikit perbedaan semantik antara a = a & b;dan a = a && b;. (Jika bvariabel atau konstanta, hasilnya akan sama untuk kedua versi. Hanya ada perbedaan semantik ketika bsubekspresi yang memiliki efek samping. Dalam &kasus ini, efek samping selalu terjadi. Dalam &&hal itu terjadi tergantung pada nilaia .)

Di sisi kinerja, trade-off adalah antara biaya evaluasi b, dan biaya tes dan cabang dari nilai a, dan potensi penghematan dari menghindari penugasan yang tidak perlu a. Analisisnya tidak langsung, tetapi kecuali biaya penghitungannya btidak sepele, perbedaan kinerja antara kedua versi terlalu kecil untuk dipertimbangkan.

Stephen C
sumber
Paragraf "dalam praktik" Anda menyesatkan. Satu-satunya alasan untuk menggunakan & lebih && adalah untuk menghitung subekspresi yang tidak sepele dalam "b"
AlexP
Diklarifikasi. (Sebenarnya, hal-hal sepele tidak benar-benar masuk ke dalamnya.)
Stephen C
51

lihat 15.22.2 JLS . Untuk operan boolean, &operator adalah boolean, bukan bitwise. Satu-satunya perbedaan antara &&dan &untuk operan boolean adalah untuk&& pendek (artinya operan kedua tidak dievaluasi jika operan pertama bernilai false).

Jadi dalam kasus Anda, jika badalah primitif, a = a && b, a = a & b, dan a &= bsemua melakukan hal yang sama.

rebus
sumber
2
Jadi (a & = b;) tidak akan mengalami hubungan pendek jika b adalah pemanggilan metode? apakah ada sesuatu seperti operator "&& ="?
is7s
2
Tampaknya ini tidak menjawab pertanyaan; OP sudah tahu tentang hubungan arus pendek.
ATAU Mapper
21

Yang terakhir:

a = a & b;
Philippe Leybaert
sumber
0

Berikut cara sederhana untuk mengujinya:

public class OperatorTest {     
    public static void main(String[] args) {
        boolean a = false;
        a &= b();
    }

    private static boolean b() {
        System.out.println("b() was called");
        return true;
    }
}

Keluarannya b() was called, oleh karena itu operan tangan kanan dievaluasi.

Jadi, seperti yang sudah disebutkan oleh orang lain, a &= bsama dengan a = a & b.

pengguna7291698
sumber
-2

saya menemukan situasi yang sama menggunakan boolean di mana saya ingin menghindari memanggil b () jika sudah salah.

Ini bekerja untuk saya:

a &= a && b()
Daniel Testa
sumber
25
Untuk menghindari redudansi (masih memungkinkan terjadinya hubungan arus pendek), Anda cukup menulis a=a&&b().
Unai Vivi