当前位置: 首页 > news >正文

Android/Java中枚举的详解

Android/Java 中带属性和不带属性枚举的详细解析

一、不带属性的枚举(简单枚举)

定义方式

// 最简单的枚举定义
public enum DayOfWeek {MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY,SATURDAY,SUNDAY
}// 带有方法的简单枚举
public enum Status {PENDING,PROCESSING,COMPLETED,FAILED;// 可以添加方法public boolean isFinished() {return this == COMPLETED || this == FAILED;}
}

使用场景

  1. 简单的状态标识
  2. 有限的选项集合
  3. 不需要额外数据的常量

使用方法

public class SimpleEnumExample {// 作为方法参数(类型安全)public void setDay(DayOfWeek day) {switch (day) {case MONDAY:System.out.println("周一工作");break;case FRIDAY:System.out.println("周五愉快");break;case SATURDAY:case SUNDAY:System.out.println("周末休息");break;}}// 遍历所有枚举值public void printAllDays() {for (DayOfWeek day : DayOfWeek.values()) {System.out.println(day.name() + " - " + day.ordinal());}}// 使用枚举方法public void checkStatus(Status status) {if (status.isFinished()) {System.out.println("任务已完成或失败");} else {System.out.println("任务进行中");}}
}

Android 中的实际应用

// 网络请求状态
public enum NetworkState {IDLE,LOADING,SUCCESS,ERROR
}public class NetworkManager {private NetworkState currentState = NetworkState.IDLE;public void startRequest() {currentState = NetworkState.LOADING;// 网络请求逻辑}public NetworkState getCurrentState() {return currentState;}public boolean isBusy() {return currentState == NetworkState.LOADING;}
}

二、带属性的枚举(复杂枚举)

定义方式

// 带属性的枚举定义
public enum HttpStatus {// 枚举值及其属性OK(200, "OK", "请求成功"),CREATED(201, "Created", "资源创建成功"),BAD_REQUEST(400, "Bad Request", "客户端请求错误"),NOT_FOUND(404, "Not Found", "资源未找到"),INTERNAL_ERROR(500, "Internal Server Error", "服务器内部错误");// 属性字段(通常为final)private final int code;private final String reason;private final String description;// 构造函数(默认为private)HttpStatus(int code, String reason, String description) {this.code = code;this.reason = reason;this.description = description;}// Getter方法public int getCode() {return code;}public String getReason() {return reason;}public String getDescription() {return description;}// 工具方法public boolean isSuccess() {return code >= 200 && code < 300;}public boolean isError() {return code >= 400;}// 静态查找方法public static HttpStatus fromCode(int statusCode) {for (HttpStatus status : values()) {if (status.code == statusCode) {return status;}}return INTERNAL_ERROR;}
}

更复杂的带属性枚举示例

public enum PaymentMethod {// 枚举值带多个属性ALIPAY("alipay", "支付宝", R.drawable.ic_alipay, true, 0.0),WECHAT_PAY("wechat", "微信支付", R.drawable.ic_wechat, true, 0.001),CREDIT_CARD("credit", "信用卡", R.drawable.ic_credit_card, false, 0.015),BANK_TRANSFER("bank", "银行转账", R.drawable.ic_bank, true, 0.005);private final String code;private final String displayName;private final int iconRes;private final boolean available;private final double feeRate;PaymentMethod(String code, String displayName, int iconRes, boolean available, double feeRate) {this.code = code;this.displayName = displayName;this.iconRes = iconRes;this.available = available;this.feeRate = feeRate;}// Getter方法public String getCode() { return code; }public String getDisplayName() { return displayName; }public int getIconRes() { return iconRes; }public boolean isAvailable() { return available; }public double getFeeRate() { return feeRate; }// 业务方法public double calculateFee(double amount) {return amount * feeRate;}public String getFormattedFee(double amount) {return String.format("手续费: ¥%.2f", calculateFee(amount));}// 静态工具方法public static List<PaymentMethod> getAvailableMethods() {List<PaymentMethod> available = new ArrayList<>();for (PaymentMethod method : values()) {if (method.available) {available.add(method);}}return available;}
}

三、两种枚举的使用对比

简单枚举的使用

public class SimpleEnumUsage {public void processOrder(OrderStatus status) {// 使用switch语句switch (status) {case OrderStatus.PENDING:System.out.println("订单待处理");break;case OrderStatus.PROCESSING:System.out.println("订单处理中");break;case OrderStatus.SHIPPED:System.out.println("订单已发货");break;case OrderStatus.DELIVERED:System.out.println("订单已送达");break;case OrderStatus.CANCELLED:System.out.println("订单已取消");break;}// 使用if语句if (status == OrderStatus.DELIVERED) {System.out.println("发送满意度调查");}}
}

带属性枚举的使用

public class ComplexEnumUsage {public void handleHttpResponse(int statusCode) {HttpStatus status = HttpStatus.fromCode(statusCode);// 使用枚举属性System.out.println("状态码: " + status.getCode());System.out.println("原因: " + status.getReason());System.out.println("描述: " + status.getDescription());// 使用枚举方法if (status.isSuccess()) {System.out.println("请求成功");} else if (status.isError()) {System.out.println("请求出错");}}public void processPayment(PaymentMethod method, double amount) {if (!method.isAvailable()) {throw new IllegalStateException("支付方式不可用");}double fee = method.calculateFee(amount);double total = amount + fee;System.out.println("使用: " + method.getDisplayName());System.out.println("金额: ¥" + amount);System.out.println("手续费: ¥" + fee);System.out.println("总计: ¥" + total);}
}

四、Android 中的实际应用案例

案例1:主题切换(简单枚举)

public enum AppTheme {LIGHT,DARK,SYSTEM
}public class ThemeManager {private AppTheme currentTheme = AppTheme.SYSTEM;public void applyTheme(AppTheme theme) {this.currentTheme = theme;switch (theme) {case LIGHT:AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);break;case DARK:AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);break;case SYSTEM:AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM);break;}// 保存到SharedPreferencessaveThemePreference(theme);}public AppTheme getCurrentTheme() {return currentTheme;}
}

案例2:用户权限管理(带属性枚举)

public enum UserPermission {// 权限定义READ("read", "读取权限", 1),WRITE("write", "写入权限", 2),DELETE("delete", "删除权限", 3),ADMIN("admin", "管理权限", 4),SUPER_USER("super", "超级用户权限", 5);private final String code;private final String description;private final int level;UserPermission(String code, String description, int level) {this.code = code;this.description = description;this.level = level;}public String getCode() { return code; }public String getDescription() { return description; }public int getLevel() { return level; }// 权限检查方法public boolean canGrant(UserPermission other) {return this.level >= other.level;}public boolean canRevoke(UserPermission other) {return this.level > other.level;}// 根据代码获取权限public static UserPermission fromCode(String code) {for (UserPermission permission : values()) {if (permission.code.equals(code)) {return permission;}}throw new IllegalArgumentException("未知权限: " + code);}
}public class PermissionManager {private UserPermission currentPermission;public boolean hasPermission(UserPermission required) {return currentPermission != null && currentPermission.getLevel() >= required.getLevel();}public boolean canGrantPermission(UserPermission target) {return currentPermission != null && currentPermission.canGrant(target);}
}

五、枚举的高级特性

1. 枚举实现接口

public interface Operation {double apply(double a, double b);
}public enum MathOperation implements Operation {ADD {@Overridepublic double apply(double a, double b) {return a + b;}},SUBTRACT {@Overridepublic double apply(double a, double b) {return a - b;}},MULTIPLY {@Overridepublic double apply(double a, double b) {return a * b;}},DIVIDE {@Overridepublic double apply(double a, double b) {if (b == 0) throw new ArithmeticException("除数不能为零");return a / b;}};
}// 使用
double result = MathOperation.ADD.apply(5, 3); // 8.0

2. 枚举中的抽象方法

public enum FileType {TEXT {@Overridepublic String getMimeType() {return "text/plain";}@Overridepublic boolean isEditable() {return true;}},IMAGE {@Overridepublic String getMimeType() {return "image/jpeg";}@Overridepublic boolean isEditable() {return false;}},PDF {@Overridepublic String getMimeType() {return "application/pdf";}@Overridepublic boolean isEditable() {return false;}};public abstract String getMimeType();public abstract boolean isEditable();
}

六、性能考虑和最佳实践

1. 内存考虑

  • 简单枚举:内存占用小,适合大量使用
  • 带属性枚举:每个枚举值都是对象实例,占用更多内存

2. Android 中的优化

// 对于性能敏感的场景,可以使用@IntDef/@StringDef
@IntDef({Theme.LIGHT, Theme.DARK, Theme.SYSTEM})
@Retention(RetentionPolicy.SOURCE)
public @interface Theme {int LIGHT = 0;int DARK = 1;int SYSTEM = 2;
}public void applyTheme(@Theme int theme) {// 使用int值而不是枚举
}

3. 最佳实践

  • 使用final字段:确保枚举的不可变性
  • 提供完整的API:包括Getter、工具方法、查找方法等
  • 添加合适的注释:说明每个枚举值的用途
  • 考虑序列化:在Parcelable中正确处理枚举
// Parcelable中的枚举处理
public class Settings implements Parcelable {private AppTheme theme;protected Settings(Parcel in) {theme = AppTheme.valueOf(in.readString());}@Overridepublic void writeToParcel(Parcel dest, int flags) {dest.writeString(theme.name());}
}

总结对比

特性不带属性枚举带属性枚举
定义复杂度简单复杂
内存占用较大
功能丰富度有限丰富
适用场景简单状态标识需要额外数据的复杂场景
可读性一般优秀
灵活性

选择建议:

  • 如果只需要表示简单的状态或选项,使用不带属性枚举
  • 如果需要附加数据、方法或复杂逻辑,使用带属性枚举
  • 在性能极其敏感的Android场景中,考虑使用注解替代枚举
http://www.xdnf.cn/news/1373617.html

相关文章:

  • 基于Spring Boot+Vue的生活用品购物平台/在线购物系统/生活用户在线销售系统/基于javaweb的在线商城系统
  • JMeter —— 压力测试
  • 基于 Docker Compose 的若依多服务一键部署java项目实践
  • C# OpenCVSharp 实现物体尺寸测量方案
  • 【Java】异常处理:从入门到精通
  • npm run start 的整个过程
  • 文字样式设置
  • Python基础、数据科学入门NumPy(数值计算)、Pandas(数据处理)、Matplotlib(数据可视化)附视频教程
  • 使用Spring Boot和EasyExcel导出Excel文件,并在前端使用Axios进行请求
  • 部署网页在服务器(公网)上笔记 infinityfree 写一个找工作单html文件的网站
  • 趣味学Rust基础篇(变量与可变性)
  • 从传统到创新:用报表插件重塑数据分析平台
  • 基于Spark的白酒行业数据分析与可视化系统的设计与实现
  • 【服务器】用X99主板组装服务器注意事项
  • 【开题答辩全过程】以 微信小程序的医院挂号预约系统为例,包含答辩的问题和答案
  • 在Excel和WPS表格中通过查找替换对单元格批量强制换行
  • 实现基于数据库 flag 状态的消息消费控制
  • PMP项目管理知识点-⑭【①-⑬流程总结】→图片直观表示
  • 让ai写一个类github首页
  • 从文本到二进制:HTTP/2不止于性能,更是对HTTP/1核心语义的传承与革新
  • 深度学习11 Deep Reinforcement Learning
  • 深度学习12 Reinforcement Learning with Human Feedback
  • 如何在阿里云百炼中使用钉钉MCP
  • 深度学习——激活函数
  • 【stm32简单外设篇】-4×4 薄膜键盘
  • 区块链技术探索与应用:从密码学奇迹到产业变革引擎
  • 【PS实战】制作hello标志设计:从选区到色彩填充的流程(大学作业)
  • 开发electron时候Chromium 报 Not allowed to load local resource → 空白页。
  • 【分布式技术】Kafka 数据积压全面解析:原因、诊断与解决方案
  • 基于muduo库的图床云共享存储项目(一)