介绍
位运算符用来对二进制位进行操作。
int a = 12; //0000 0000 0000 0000 0000 0000 0000 1100
int b = -5; //1111 1111 1111 1111 1111 1111 1111 1011
a & b = 8; //0000 0000 0000 0000 0000 0000 0000 1000
a | b = -1; //1111 1111 1111 1111 1111 1111 1111 1111
a ^ b = -9; //1111 1111 1111 1111 1111 1111 1111 0111
~b = 4; //0000 0000 0000 0000 0000 0000 0000 0100
a << 1 = 24; //0000 0000 0000 0000 0000 0000 0001 1000 空位用0补
b << 1 = -10; //1111 1111 1111 1111 1111 1111 1111 0110 空位用0补
a >> 1 = 6; //0000 0000 0000 0000 0000 0000 0000 0110 空位用符号位的值补
b >> 1 = -3; //1111 1111 1111 1111 1111 1111 1111 1101 空位用符号位的值补
a >>> 1 = 6; //0000 0000 0000 0000 0000 0000 0000 0110 空位用0补
b >>> 1 = 2147483645;//0111 1111 1111 1111 1111 1111 1111 1101 空位用0补
操作符 | 名称 | 描述 | 范例 |
---|---|---|---|
& | 按位与 | 对应位都是1,结果为1,否则为0 | a & b |
| | 按位或 | 对应位都是0,结果为0,否则为1 | a | b |
^ | 按位异或 | 对应位值不同,结果为1,否则为0 | a ^ b |
~ | 非 | 翻转操作数的每一位,即0变成1,1变成0 | ~ a |
<< | 左移 | 操作数按位左移右操作数指定的位数,移动得到的空位以0填充。 | a << 1 |
>> | 右移 | 操作数按位右移右操作数指定的位数,移动得到的空位以符号位的值填充。 | a >> 1 |
>>> | 无符号右移 | 操作数按位右移右操作数指定的位数,移动得到的空位以0填充。 | a >>> 1 |
优先级
~
<<、>>、>>>
&
^
|
从上到下表示优先级高到低。关联性从左到右。
用法
在android的view中关于visibility的代码,用于设置view的可见性。
public static final int VISIBLE = 0x00000000;//标记view是可见的
public static final int INVISIBLE = 0x00000004;//标记view是不可见的
public static final int GONE = 0x00000008;//标记view是死了的
static final int VISIBILITY_MASK = 0x0000000C;//setFlags时表明那些字节用于visibility
int mViewFlags;//持有各种各样的view的状态
public void setVisibility(@Visibility int visibility) {
setFlags(visibility, VISIBILITY_MASK);
}
void setFlags(int flags, int mask) {
······
int old = mViewFlags;
mViewFlags = (mViewFlags & ~mask) | (flags & mask);//这行代码等于下面两行
//mViewFlags &= ~mask;//清除标记,只会清除visibility相关字节。
//mViewFlags |= flags & mask;//添加标记,flags & mask保证标记只会添加到visibility相关的字节中。
int changed = mViewFlags ^ old;//查看标记是否有改变
if (changed == 0) {
return;
}
······
}
public int getVisibility() {
return mViewFlags & VISIBILITY_MASK;//查看标记
}
用一个int类型的mViewFlags持有各种各样的view的状态,用一个int类型的静态常量VISIBILITY_MASK来表明那些字节用于visibility。对标记的操作:
- 添加标记:mViewFlags |= flags & mask
- 清除标记:mViewFlags &= ~mask
- 查看标记:mViewFlags & VISIBILITY_MASK
这样的写法有什么好处呢?
- 位运算效率高。
- 节省了内存空间(多个view的状态存在一个int里面,只通过一个静态常量表示所占用的字节)
android中很多源码都使用了这个写法。