/** * Operation-set bit for read operations. * * <p> Suppose that a selection key's interest set contains * <tt>OP_READ</tt> at the start of a <a * href="Selector.html#selop">selection operation</a>. If the selector * detects that the corresponding channel is ready for reading, has reached * end-of-stream, has been remotely shut down for further reading, or has * an error pending, then it will add <tt>OP_READ</tt> to the key's * ready-operation set and add the key to its selected-key set. </p> */ public static final int OP_READ = 1 << 0;
在剛接觸到SelectionKey時其實是有點暈的,好好的一個1,爲何要用1<<0來表示?讀權限是1,爲何寫權限又是4?(1<<2)。html
爲何不用1來表明寫權限,2來表明讀權限,3表明只寫,4表明只讀,5表明可讀可寫呢?實際上即便是這樣,對計算機來講,也不是什麼負擔,只要文檔寫清楚,對人來講也不是很難看懂。java
上面那種表示方式固然能夠,但若是有10個權限,那麼咱們的文檔會變得十分複雜,好比說若是我想要增、刪、改、查、移權限,又該怎麼表示?若是我不想要讀權限了,只要增、改、查,又該怎麼表示?linux
在查閱資料後發現這是一種巧妙的權限設計方式:設計
1<<0 表明 二進制的1向左移零位,也就是將 0000 0001 變成了 0000 0001,仍是1 1<<2 表明 二進制的1向左移兩位,也就是將 0000 0001 變成了 0000 0100,也就是4rest
從二進制的角度來判斷有沒有權限,好比說第一位是1,表明有讀取權限,第三位是1,表明有寫入權限。 那麼 1<<0 就表明 只讀(沒有寫),1<<2 就表明只寫(不可讀)code
那麼如今就很清晰明瞭 若是說 00000 分別表明增、刪、改、查、移,那麼 10010 ,意思就是擁有新增和查詢的權限。htm
事情不是這樣就完了!用二進制來表達權限後,再輔以位運算,咱們的權限系統會若有神助。rem
最簡單的一個需求,我想要給我本身新增一個修改的權限。文檔
if (permission.has(update)){ return; } else { permission.add(update); }
搞定!10秒鐘都不用。新需求:如今還須要添加一個讀權限!it
if (permission.has(select)){ return; } else { permission.add(select); }
輕鬆加愉快。
若是這樣寫代碼的話,就算是糟蹋了當初設計這個權限系統的人的一番心血。
還說說增、刪、改、查、移這五個權限,好比說如今我只有刪除權限 0000 1000。 我想加一個查詢權限,只須要 0000 1000 | 0000 0010
按位或,如其名,同位只要有一個是1,就取1。
0000 1000 | 0000 0010
獲得結果 0000 1010,表明我同時擁有 2號 和 4號權限,即刪、查權限。 這時候來了一個新需求,我要添加增、刪、改、移這四個權限。也就是添加 0001 1101 這四個權限。
0000 1010 | 0001 1101
獲得結果 0001 1111,我同時擁有了全部權限,按位或完美實現了 「有則不變,無則新增」 這個功能。
好比說如今個人權限是 0001 1101,我想刪除增長的權限(0001 0000)。
能夠這樣寫:0001 1101 &~ 0001 0000
運算的意思是: 先將 0001 0000 取反,獲得 1110 1111, 再進行與運算,按位與,也如其名,同位要都是1,才能是1。
0001 1101 & 1110 1111
獲得結果 0000 1101,個人增長權限沒了!只剩下刪、改、移
若是咱們要刪除增、刪、改( 0001 1100 ) 這三個權限呢?
同樣,將 0001 1100 取反,獲得 1110 0011。
1110 0011& 0000 1101
獲得結果 0000 0001 ,也就是說,我只剩下移動的權限了。使用 &~ 按位與、按位取反,很容易的就實現了 「有則刪除,無則不變」 的功能。
經過 與、或、取反,咱們實現了增、刪功能,那查詢功能呢?
好比說咱們如今有權限:0001 1101,我想知道我是否有移動的權限,那麼我能夠按位與移動權限,即 0000 0001
按位與後獲得 0000 0001,表明我有移動的權限,獲得 0000 0000 則表明我沒有移動的權限。
因此咱們能夠得知,判斷是否擁有某個權限,或者擁有列舉的全部權限,或者只須要如下代碼:
boolean hasPer = (myPermission & comparePermission) == comparePermission 便可。
那如何判斷有用列舉的其中一個權限便可呢?
很簡單....反過來想,若是沒有全部的權限,那麼確定獲得 0000 0000。
因此:boolean hasOneOfPer = (myPermission & comparePermission) != 0
若是有接觸過linux系統的小夥伴確定據說過權限 777 、12三、000、等。
實際上這個數字 0 - 7 就是二進制權限的一種設計。
7轉換成二進制,就是 111,表明 rwx,分別是 讀、寫、執行。
777 的意思是,文件全部者、同組用戶、其餘組用戶都擁有 讀、寫執行的權限。
776 呢? 6 轉換爲二進制 便是 110,表明文件全部者、同組用戶、擁有 讀、寫執行的權限,而其餘組用戶只有 讀、寫權限,沒有執行權限。