位运算实现权限管理及实现原理

在实际开发中,往往一个类对象拥有多种权限,每种权限有两个状态即有和无,正常情况下,有多少个权限,就需要多少个字段保存相应状态,如果权限过多,那么这种方式显得极其笨重,最近学习了一种用一个int字段实现的权限管理的方式,方便快捷,实现原理简单,大大简化操作,用了一上午时间研究,简单实现了8个权限的管理(实际上int字段可以管理32位,与8位管理没有本质区别),现就实现过程及内部原理做一个简单总结

1.需要了解的基础知识  ——JAJA中基本数据类型所占的空间:

java基本数据类型 四类八种:byte(1字节),short(2字节),int(4字节),long(8字节),char(1字节),boolean(1字节),float(4字节),double(8字节),其中1字节=8位,所以 int类型在计算机内存中占32位

2.需要了解的基础知识 ——JAVA中的位运算符,这里用到的 & (与) 、|(或) 、 ~(非)

简单运算(都是二进制的数据)

1 & 1 = 1                            1 | 1 = 1                     ~0 = 1

1 & 0 = 0                            1 | 0 = 1                     ~1 = 0

0 & 1 = 0                            0 | 1 = 1

0 & 0 =0                             0 | 0 = 0

了解以上基础知识后,简单的写一个小demo,尝试一下利用位运算管理权限的方便之处(如果是十进制的数参与位运算,首先将十进制的数转换为二进制,运算结束后再转为十进制,这些都是计算机自动完成的)

 

public class Authority {
    //新增权限
    private static final int ALLOW_INSERT   = 1 << 0;
    //删除权限
    private static final int ALLOW_DELETE   = 1 << 1;
    //修改权限
    private static final int ALLOW_UPDATE   = 1 << 2;
    //查看权限
    private static final int ALLOW_SELECT   = 1 << 3;
    //可读权限
    private static final int ALLOW_READ     = 1 << 4;
    //可写权限
    private static final int ALLOW_WRITE    = 1 << 5;
    //复制权限
    private static final int ALLOW_COPY     = 1 << 6;
    //只读权限
    private static final int ALLOW_READONLY = 1 << 7;
    //用来保存当前存在的权限,即用这一个字段,保存8种权限状态
    private int state;
    //设置权限,1个或多个
    public void setAuto(int auto) {
        state =  auto;
    }
    //用来增加一个权限,一个或多个
    public void addAuto(int auto) {
        state = state | auto ;
    }
    //用来删除一个权限
    public void delAuto(int auto) {
        state = state &~auto;
    }
    //用来查看是否有某种权限
    public boolean isAllow(int auto) {
        return ((state & auto) == auto);
    }
    //用来查看是否没有某种权限
    public boolean isNotAllow(int auto) {
        return ((state & auto) == 0);
    }

}

public static void look(Authority auto) {
        System.out.println("ALLOW_INSERT   有权限:"+ auto.isAllow(ALLOW_INSERT));
        System.out.println("ALLOW_DELETE   有权限:"+ auto.isAllow(ALLOW_DELETE));
        System.out.println("ALLOW_UPDATE   有权限:"+ auto.isAllow(ALLOW_UPDATE));
        System.out.println("ALLOW_SELECT   有权限:"+ auto.isAllow(ALLOW_SELECT));
        System.out.println("ALLOW_READ     有权限:"+ auto.isAllow(ALLOW_READ));
        System.out.println("ALLOW_WRITE    有权限:"+ auto.isAllow(ALLOW_WRITE));
        System.out.println("ALLOW_COPY     有权限:"+ auto.isAllow(ALLOW_COPY));
        System.out.println("ALLOW_READONLY 有权限:"+ auto.isAllow(ALLOW_READONLY));
    }

 

 

以上就是用int字段管理8个权限状态的demo全部代码,这8个权限的状态是我随便起的,不要在意这些细节

写一个测试方法验证一下

public static void main (String[] args){

    //测试一:设置某个对象拥有8种权限

    Authority auto = new Authority();

    auto.setAuto((1 << 8) -1);

    look(auto);

    打印结果显示所有权限都为  true

    //测试二 在所有权限都有的基础上,删除 增删改查权限

    auto.delAuto(ALLOW_INSERT | ALLOW_DELETE | ALLOW_UPDATE | ALLOW_SELECT);

     look(auto); 

    打印结果显示  增删改查权限为false

    //测试三  在测试二基础上增加 删除权限

   auto.addAuto(ALLOW_DELETE );

   look(auto); 

   打印结果显示删除权限增加成功

   到这里基本功能演示完毕,一个int字段可以保存多种状态,下面简单解释一下内部原理

   1.首先先定义8种状态,每种状态都是在二进制下位数左移得到的,即

      0000 0000 0000 0000 0000 0000 0000 0001     代表  1  << 0;

     由于这里演示8种状态,只写8位,前面的 0 全部省略

     0000 0001     1  << 0          ALLOW_INSERT

     0000 0010     1 << 1           ALLOW_DELETE

     0000 0100     1 << 2           ALLOW_UPDATE

     0000 1000     1 << 3           ALLOW_SELECT

     0001 0000     1 << 4           ALLOW_READ

     0010 0000     1 << 5           ALLOW_WRITE

     0100 0000     1 << 6           ALLOW_COPY

     1000 0000     1 << 7           ALLOW_READONLY

以上不难看出,这8个位上,有1的代表有权限,有0的代表无权限,这样每个位分别控制一种权限,8个位的组合就可以实现8种权限的管理

1.设置权限   setAuto(int auto){

                       state = auto;

                      }

其实现是这样,传进去一个int值,一个值代表一个权限,可以传入多个。用位运算符号 “|” 连接参数 ,比如 传入增删权限

                    增权限     ALLOW_INSERT      其二进制形式  0000 0001

                    删权限     ALLOW_DELETE     其二进制形式  0000 0010

                                    根据位运算原理,两个二进制的数求或

                                                 0000 0001

                                         |       0000 0010

                                                 0000 0011        

                                     不难看出后两位增删权限都是1,这说明目前有增删权限,其余权限都为0即没有权限

2.删除权限      public void delAuto(int auto) {
                           state = state &~auto;
                        }      

                        代码解释:设置state状态为      当前状态 与上 传进来的int值的求非,例如目前有增删权限,需要删除增权限

                        根据位运算原理        0000 0011   &   ~ 0000  0001         

                         第一步        ~ 0000  0001     的值为   1111 1110

                         第二部        0000 0011   &    1111 1110

                          0000 0011

                  &      1111 1110 

                          0000 0010

                     得到结果  0000 0010  可以看出,增加权限位上的数字为0 ,代表没有增权限,只有删权限

3.查看是否拥某个有权限

                    public boolean isAllow(int auto) {
                        return ((state & auto) == auto);
                    }

        设当前 拥有增删权限       0000 0011

        传入int值        ALLOW_INSERT   其二进制是 0000 0001,代表查看是否有增权限

        (0000 0011 & 0000 0001)的值为 0000 0001

         上面提到,如果是位运算,计算机会将数字转为二进制计算,再将结果转为十进制

         ==是逻辑运算符,需要转成十进制计算

         0000 0001 的十进制是1 ,传入的参数 0000 0001 也是 1   ,1 == 1  结果为true 

        即0000 0011有增权限,其他方法也是通过这种位运算计算得出的结果,不一一演示

              

      

 

}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值