前沿
最近在看反射,发现反射中有一个Modifier类,Filed、Consturctor、Method中都有getModifiers()方法,方法返回表示此对象的java语言修饰符,返回值类型为int,这里有个疑问为什么int的数字可以表示java修饰符,因为好奇,点进源码一探究竟。
首先,我们看看Modifier类中定义的静态常量,采用16进制计数
/**
* The {@code int} value representing the {@code public}
* modifier.
*/
public static final int PUBLIC = 0x00000001;
/**
* The {@code int} value representing the {@code private}
* modifier.
*/
public static final int PRIVATE = 0x00000002;
/**
* The {@code int} value representing the {@code protected}
* modifier.
*/
public static final int PROTECTED = 0x00000004;
/**
* The {@code int} value representing the {@code static}
* modifier.
*/
public static final int STATIC = 0x00000008;
再看看它的静态方法,采用的是位与运算,如果getModifiers()方法的返回值&public对应的16进制值为非0的话,就说明含有public修饰符
public static boolean isPublic(int mod) {
return (mod & PUBLIC) != 0;
}
扩展
如果只是针对两个状态字段的判断,我们就可以采用位运算来表示就很方便了。
比如说用户的状态类,用户是否完成手机认证,是否完成邮箱认证,是否完成基本资料等等,如果单独都写一个字段表示的话,数据库多一个状态就多需要多一列来表示。我们可不可以用一列可以表示完所有的状态呢?答案是肯定可以的,我们可以采用位运算来表示。举例说明:我们新建一个记录状态的类BitStates,创建所需要表示的状态,如下
/**
* 是否手机认证
*/
public final static int OP_AUTHED_PHONE = 1 << 3;
/**
* 是否邮箱认证
*/
public final static int OP_AUTHED_EMAIL = 1 << 4;
/**
* 是否完善个人信息
*/
public final static int OP_SAVE_BASIC_INFO = 1 << 5;
简单的说下1 << 3表示的是位运算的左移3位,比如0000 0001左移三位则变成0000 1000,表示的数值就是8,1 << 4左移4位则是0001 0000表示的数值是16,这样一个位就可以用于表示一个状态,也有相对应的值,当然int类型是32位的,这里只是简单描述下。
那么问题来了
- 如何表示新增状态
- 如何删除状态
- 如何查询状态
比如:用户表中的状态值为24,换成二进制位00011000,想知道用户是否完成手机认证,采用 & 运算,规则是同为1则为1,否则都为0
00011000
& 00001000
= 00001000
结果:刚好等于是否手机认证的值,说明包含手机认证状态
接着上面的状态值,如果想添加某一状态,比如用户已完成基本资料,采用 | 运算,规则是只有同为0则为0,否则为1
00011000
| 00100000
= 00111000
结果:在原来的基础上增加了一个状态
如果删除一个状态,我想删除手机认证,采用 ^ 运算,规则是相同为0,不同为1,我每次记的时候是只有异性才可以生成孩子,同性不行
00111000
^ 00001000
= 00110000
结果:在原来的基础上少了一个状态
代码如下:
/**
* @param states 用户当前状态值
* @param value 需要判断状态值
* @return 是否存在
*/
public static boolean hasState(long states,long value){
return (states & value) == value;
}
/**
* @param states 已有状态值
* @param value 需要添加状态值
* @return 新的状态值
*/
public static long addState(long states,long value){
if(hasState(states, value)){
return states;
}
return (states | value);
}
/**
* @param states 已有状态值
* @param value 需要删除状态值
* @return 新的状态值
*/
public static long removeState(long states,long value){
if(!hasState(states, value)){
return states;
}
return states ^ value;
}