(1) Does it perform some kind of bit manipulation?
If you use |
with numeric operands then yes, it will be bitwise OR, if you use it on boolean operands it will be logical (non-short-circuit) OR. Example
Logical OR: lets say that 1
represents true
and 0
false
+---+---+-------+
| p | q | (p|q) |
+---+---+-------+
| 0 | 0 | 0 |
| 0 | 1 | 1 |
| 1 | 0 | 1 |
| 1 | 1 | 1 |
+---+---+-------+
Bitwise OR will perform similar operation as boolean but will use corresponding bits
decimal binary
6 = 00110
3 = 00011
OR -------------
00111
(2) What does this mark exactly do?
x |= y
is the same as x = x | y
so it will calculate x | y
and store it in x
.
(3) Are there any other well known signs similar to this?
Yes, every arithmetic, bitwise or bit shift operator can be used this way: +=
-=
*=
/=
%=
&=
^=
|=
<<=
>>=
>>>=
Here are some additional informations about usage of |=
in
notification.flags |= Notification.FLAG_AUTO_CANCEL;
Lets say that we have five properties.
Property1
Property2
Property3
Property4
Property5
We can use last five bits of number to represents situations where we have (1) or don't have (0) some property.
...00xxxxx
│││││
││││└─ flag for Property1
│││└── flag for Property2
││└─── flag for Property3
│└──── flag for Property4
└───── flag for Property5
Now, lets say that we want to use only properties 1, 2 and 4. To do this we have to set bits indexed with 0, 1 and 3 to value 1 like
...0001101
│││││
││││└─ (1) has Property1
│││└── (0) no Property2
││└─── (1) has Property3
│└──── (1) has Property4
└───── (0) no Property5
In other words we have to produce number 13 (= **1***8 + **1***4 + **0***2 + **1***1). We can do this with |
OR bitwise operator 8|4|1
because
8 = ...001000
4 = ...000100
1 = ...000001
OR -------------
13 = ...001101
But to avoid magic numbers we can create constants that will represents our properties in bit world. So we can create
public class MyProperties {
//...
public static final int PROPERTY_1 = 0b0000_0001; // = 1
public static final int PROPERTY_2 = 0b0000_0010; // = 2
public static final int PROPERTY_3 = 0b0000_0100; // = 4
public static final int PROPERTY_4 = 0b0000_1000; // = 8
public static final int PROPERTY_5 = 0b0001_0000; // = 16
//...
//rest of code: methods, constructors, other fields
}
and use it later like
int context = Properties.PROPERTY_1|Properties.PROPERTY_2|Properties.PROPERTY_4
which is more readable than int context = 8|4|1
.
Now if we want to change our context and lets say add PROPERTY_3
we can use
context = context | Properties.PROPERTY_3;
or shorter version based on compound assignments operators
context |= Properties.PROPERTY_3;
which will do this calculations
context = 000...00001101
PROPERTY_3 = 000...00000010
OR ------------------------
000...00001111
(main difference between adding value of PROPERTY_3
to context
and using bitwise OR |
is that when context
will already have PROPERTY_3
set to 1
then OR will no effect it).
Now if you take a look here idea of using single bits as flags for properties was used in Notification
class, where FLAG_AUTO_CANCEL
constant has value 16
(0x010
in hexadecimal, 0b0001_0000
in binary).