java移位掩码_Java中的位掩码BitMask

JDK源码的使用

最近在JDK源码中闲逛,无意中看到了java.lang.reflect.Modifier这个类,这个类很简单,都是些常量定义和判断方法,于是扒了扒代码实现的含义,我们就看个isPublic方法吧:

/**

* Return {@code true} if the integer argument includes the

* {@code public} modifier, {@code false} otherwise.

*

* @param mod a set of modifiers

* @return {@code true} if {@code mod} includes the

* {@code public} modifier; {@code false} otherwise.

*/

public static boolean isPublic(int mod) {

return (mod & PUBLIC) != 0;

}

/**

* The {@code int} value representing the {@code public}

* modifier.

*/

public static final int PUBLIC = 0x00000001;

/**

* The {@code int} value representing the {@code static}

* modifier.

*/

public static final int STATIC = 0x00000008;

/**

* The {@code int} value representing the {@code final}

* modifier.

*/

public static final int FINAL = 0x00000010;

我们来看看java.lang.Class类中的几个方法:

public boolean isAnnotation() {

return (getModifiers() & ANNOTATION) != 0;

}

public boolean isEnum() {

// An enum must both directly extend java.lang.Enum and have

// the ENUM bit set; classes for specialized enum constants

// don't do the former.

return (this.getModifiers() & ENUM) != 0 &&

this.getSuperclass() == java.lang.Enum.class;

}

可以看到Class的getModifier()方法返回的整形值又能判断当前类是否是Enum,又能判断是否是Annotation。

Modifier中定义了很多modifier的值,这些值都很有规律,从前往后依次都是2的n次方的16进制表示,也就是二进制的1每次左移的结果。最后的效果就是不同类型的modifier都在二进制形式的值中占一位。比如:

PUBLIC: 0x00000001,二进制:0001

PRIVATE: 0x00000002,二进制:0010

PROTECTED:0x00000004,二进制:0100

STATIC: 0x00000008,二进制:1000

如果想表示一个类既是public又是static的时候,这时候getModifier()方法就会返回1001也就是整形9,而我们可以通过9的二进制表示来做位运算,就是文章开头的函数:

public static boolean isPublic(int mod) {

return (mod & PUBLIC) != 0;

}

这时候传入的mod为9,也就是1001,而public修饰符定义的值为0001,这两者做与运算的时候返回就是0001,该结果不为0,即当前方式是有public修饰符的。

至此,这种由单个值表示多种状态的方式就叫做Java中的位掩码。

日常工作中的使用

例如,在一个系统中,用户一般有查询(Select)、新增(Insert)、修改(Update)、删除(Delete)四种权限,四种权限有多种组合方式,也就是有16中不同的权限状态(2的4次方)。

一般情况下会想到用四个boolean类型变量来保存:

public class Permission {

// 是否允许查询

private boolean allowSelect;

// 是否允许新增

private boolean allowInsert;

// 是否允许删除

private boolean allowDelete;

// 是否允许更新

private boolean allowUpdate;

}

但是如果使用位掩码的话,就可以用和Modifier类相似的方式了(1表示允许,0表示不允许):

public class NewPermission {

public static final int ALLOW_SELECT = 1 << 0; // 0001

public static final int ALLOW_INSERT = 1 << 1; // 0010

public static final int ALLOW_UPDATE = 1 << 2; // 0100

public static final int ALLOW_DELETE = 1 << 3; // 1000

// 存储目前的权限状态

private int flag;

// 重新设置权限

public void setPermission(int permission) {

flag = permission;

}

// 添加一项或多项权限,比如当前只有select(0001),增加insert(0010)

// 0001

// 0010 |

// 0011 = 即可以select也可以insert

public void enable(int permission) {

flag |= permission;

}

// 删除一项或多项权限,比如当前可以select、insert(0011),去掉insert()

// 0010

// 1101 ~

// 0011 &

// 0001 = 即只可以select了

public void disable(int permission) {

flag &= ~permission;

}

// 是否拥某些权限

public boolean isAllow(int permission) {

return (flag & permission) == permission;

}

// 是否禁用了某些权限

public boolean isNotAllow(int permission) {

return (flag & permission) == 0;

}

// 是否仅仅拥有某些权限

public boolean isOnlyAllow(int permission) {

return flag == permission;

}

}

今天分享的就是这样一个小细节,希望对大家有帮助。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值