位運算實現權限管理及實現原理

在實際開發中,往往一個類對象擁有多種權限,每種權限有兩個狀態即有和無,正常情況下,有多少個權限,就需要多少個字段保存相應狀態,如果權限過多,那麼這種方式顯得極其笨重,最近學習了一種用一個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有增權限,其他方法也是通過這種位運算計算得出的結果,不一一演示

              

      

 

}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章