标志枚举

本文介绍了枚举类型的两种形式:简单枚举与标志枚举,并详细解释了标志枚举的设计原则及应用场景,通过文件属性设置的例子展示了如何使用标志枚举简化多属性组合的问题。

枚举分为简单枚举和标志枚举。

简单枚举包含的值不用于组合,也不用于按位比较。

标志枚举可以使用OR操作进行组合;

设计标记枚举时要注意两点:1. 指明FlagsAttribute,以指示可以将枚举作为域(即一组标志)处理;

   2. 枚举中各标志的值应该是以2的幂来赋值,即:124816…

标志枚举的作用:举个例子,假如设计一个文件属性,有HiddenReadOnlyEncrypt,文件可能具有三个属性的任意组合,如果使用简单枚举,按照排列组合,需要1 + 3 + 3 + 1 = 8个枚举数,如果属性再多的话,将需要更多的枚举数。这时就可以使用标志枚举了。

[Flags]

public enum FileProperty

{

    Hidden = 1,

    ReadOnly = 2,

    Encrypt = 4,

}

设置文件属性时,就可以利用OR自由组合:FileProperty fileP = FileProperty.Hidden | FileProperty.ReadOnly;

从这可以看出为什么标志的值要按2的幂排列,也可以看出标志多于32个时不能使用int类型的原因。相当于使用一个数组,属性的排列顺序与数组下标一一对应,当某个下标处的值为0时,表示对应的属性没有在组合中。

File类的GetAttributes()返回的就是一个枚举值的组合,如何确定组合中包含某个属性,可以使用&(and)操作符

FileAttributes attributes = File.GetAttributes(fileName);

attributes & FileAttributes.Hidden == FileAttributes.Hidde结果为true时表示存在这个属性。

### 标志枚举的概念及用法 #### 什么是标志枚举? 在编程领域,特别是像 C# 和 Java 这样的语言中,“标志枚举”是一种特殊的枚举类型。它允许单个变量存储多个值的组合。这种设计通常用于表示一组选项中的多项选择情况。通过位运算符(如按位 OR `|` 或 AND `&`),可以在一个字段中保存多种状态。 在 Java 中,虽然标准库并未直接提供类似于其他语言(如 C# 的 `[Flags]` 属性)的功能,但可以通过合理的设计实现类似的用途[^3]。 --- #### 实现方式 以下是基于 Java 枚举类型的标志枚举实现方法: 1. **定义枚举常量并赋予其对应的二进制值** 每个枚举项应具有唯一的整数值,该值通常是 2 的幂次方形式(即 1, 2, 4, 8...)。这样可以方便地利用位运算来处理多选逻辑。 2. **重载静态方法以支持集合操作** 可以为枚举类添加一些实用工具函数,例如判断某个特定标记是否存在、返回所有被设置的标记列表等。 下面是一个具体的例子展示如何创建和使用标志枚举: ```java public enum Permission { READ(1 << 0), // 0001 WRITE(1 << 1),// 0010 EXECUTE(1 << 2); // 0100 private final int mask; Permission(int mask) { this.mask = mask; } public boolean implies(Permission permission){ return (this.mask & permission.mask) != 0; } public static Set<Permission> fromMask(int mask){ return Arrays.stream(values()) .filter(p -> (p.mask & mask)!=0) .collect(Collectors.toSet()); } } ``` 上述代码片段展示了如何定义权限作为标志枚举,并提供了两个主要功能: - 判断某一项是否包含于另一个更大的集合之中 (`implies`)。 - 将给定掩码转换回实际代表的一系列项目 (`fromMask`)。 --- #### 应用场景举例 假设我们有一个文件系统需要管理用户的访问控制权,则可以用上面提到的方式简化配置过程。如果用户拥有读写执行全部三项权利的话,那么他的总权限就可以简单表达成如下所示的形式: ```java int userPermissions = Permission.READ.mask | Permission.WRITE.mask | Permission.EXECUTE.mask; if(new Permission(userPermissions).implies(Permission.READ)){ System.out.println("User has read access."); } ``` 这里需要注意的是,在真实世界的应用开发过程中,应当始终遵循最小特权原则——只授予必要的最低限度权限即可满足业务需求。 --- #### 关联技术讨论 除了单纯探讨标志枚举本身之外,还可以进一步延伸至更广泛的计算机科学主题上。例如线程安全性方面的问题就经常涉及到原子级别上的更新动作;而当面对高并发环境下的数据竞争状况时,则可能需要用到 CAS(compare-and-swap)[^2]这样的底层硬件特性保障一致性条件成立与否等问题。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值