【问题标题】:create a permission bit mask in java在java中创建权限位掩码
【发布时间】:2023-04-27 21:25:01
【问题描述】:

我想做这样的事情:

public enum Permissions
{
    CanBlah1,
    CanBlah2,
    CanBlah3
}

byte[] userPerm = Permissions.CanBlah1 | Permissions.CanBlah2;

// check permssions
//
if(userPerm && Permissions.CanBlah1 == Permissions.CanBlah1)
{
      // do something
}

你能在 Java 中那样做吗? (我来自 c# 背景)

【问题讨论】:

    标签: java bitmask


    【解决方案1】:

    您可以使用EnumSet轻松做到这一点

    import java.util.EnumSet;
    
    import static java.util.EnumSet.of;
    import static java.util.EnumSet.range;
    import static so.User.Permissions.CanBlah1;
    import static so.User.Permissions.CanBlah2;
    import static so.User.Permissions.CanBlah3;
    
    public class User {
        public enum Permissions {
            CanBlah1,
            CanBlah2,
            CanBlah3
        }
    
        public static void main(String[] args) throws Exception {
            EnumSet<Permissions> userPerms = of(CanBlah1, CanBlah2);
            System.out.println(userPerms.contains(CanBlah1)); //true
            System.out.println(userPerms.contains(CanBlah2)); //true
            System.out.println(userPerms.contains(CanBlah3)); //false
            System.out.println(userPerms.containsAll(of(CanBlah1, CanBlah3))); //false
            System.out.println(userPerms.containsAll(range(CanBlah1, CanBlah2))); //true
            System.out.println(userPerms.containsAll(range(CanBlah1, CanBlah3))); //false
        }
    
    }
    

    【讨论】:

    • 当然,EnumSet 在底层实现为位掩码。
    • 他们是。它将long 用于最多64 个Enums 字节数组,即所谓的JubmoSet
    【解决方案2】:

    这是另一个选项,类似于序数解决方案,不同之处在于您可以使用 |和 & 运算符:

     public enum Permissions {
         CanBlah1(1),
         CanBlah2(2),
         CanBlah3(4);
    
         public int value;
    
         Permissions(int value) {
             this.value = value;
         }
         public int value() {
          return value;
         }
     }
    
     public static void main(String[] args) {  
        int userPerm = Permissions.CanBlah1.value() | Permissions.CanBlah2.value();
        // check permssions
        //
        if((userPerm & Permissions.CanBlah1.value()) == Permissions.CanBlah1.value())
        {
            // do something
        }
     }
    

    或:

     public enum Permissions {
             CanBlah1,
             CanBlah2,
             CanBlah3;
    
             public int value() {
                return 1<<ordinal();
             }
         }
    
         public static void main(String[] args) {  
            int userPerm = Permissions.CanBlah1.value() | Permissions.CanBlah2.value();
            // check permssions
            //
            if((userPerm & Permissions.CanBlah1.value()) == Permissions.CanBlah1.value())
            {
                // do something
            }
         }
    

    【讨论】:

      【解决方案3】:

      虽然我不推荐它,但您可以要求枚举的 ordinal() 并将其用于位操作。当然,由于您无法定义枚举的序数,因此您必须插入虚假值才能使序数正确

      enum Example {
         Bogus,            --> 0
         This,             --> 1
         That,             --> 2
         ThisOrThat        --> 3
      };
      

      注意需要引入一个伪造的枚举,以便

      ThisOrThat.ordinal() == This.ordinal() | That.ordinal()
      

      【讨论】:

        【解决方案4】:

        如果您停留在 Java 7 之前的时代(Android),您可以尝试以下代码:

        public enum STUFF_TO_BIT_BASK {
        THIS,THAT,OTHER;
        
        public static int getBitMask(STUFF_TO_BIT_BASK... masks) {
            int res = 0;
        
            for (STUFF_TO_BIT_BASK cap : masks) {
                res |= (int) Math.pow(2, cap.ordinal());
            }
        
            return res;
        }
        
        public boolean is(int maskToCheck){
            return maskToCheck | (int) Math.pow(2, this.ordinal());
        }
        

        }

        【讨论】:

          【解决方案5】:

          据我所知,枚举类型未定义位运算符

          【讨论】:

          最近更新 更多