Appearance
🔢 枚举与注解
枚举(Enum)
枚举概述
枚举(Enumeration)是一种特殊的类,用于定义一组常量。Java 5 引入了枚举类型。
基本枚举
java
// 定义枚举
public enum Day {
MONDAY,
TUESDAY,
WEDNESDAY,
THURSDAY,
FRIDAY,
SATURDAY,
SUNDAY
}
// 使用枚举
Day today = Day.MONDAY;
System.out.println(today); // MONDAY枚举与 switch
java
Day day = Day.MONDAY;
switch (day) {
case MONDAY:
System.out.println("星期一");
break;
case TUESDAY:
System.out.println("星期二");
break;
// ...
default:
System.out.println("其他");
}枚举方法
java
// 枚举可以定义方法
public enum Day {
MONDAY("星期一"),
TUESDAY("星期二"),
WEDNESDAY("星期三"),
THURSDAY("星期四"),
FRIDAY("星期五"),
SATURDAY("星期六"),
SUNDAY("星期日");
private final String chineseName;
Day(String chineseName) {
this.chineseName = chineseName;
}
public String getChineseName() {
return chineseName;
}
}
// 使用
Day day = Day.MONDAY;
System.out.println(day.getChineseName()); // 星期一枚举方法
java
// 枚举可以定义抽象方法
public enum Operation {
ADD {
@Override
public int calculate(int a, int b) {
return a + b;
}
},
SUBTRACT {
@Override
public int calculate(int a, int b) {
return a - b;
}
},
MULTIPLY {
@Override
public int calculate(int a, int b) {
return a * b;
}
},
DIVIDE {
@Override
public int calculate(int a, int b) {
return a / b;
}
};
public abstract int calculate(int a, int b);
}
// 使用
int result = Operation.ADD.calculate(5, 3); // 8枚举常用方法
java
Day day = Day.MONDAY;
// 获取名称
String name = day.name(); // "MONDAY"
// 获取序号
int ordinal = day.ordinal(); // 0
// 比较
boolean equals = day.equals(Day.MONDAY); // true
int compare = day.compareTo(Day.TUESDAY); // -1
// 获取所有枚举值
Day[] days = Day.values();
for (Day d : days) {
System.out.println(d);
}
// 根据名称获取枚举
Day monday = Day.valueOf("MONDAY");注解(Annotation)
注解概述
注解(Annotation)是 Java 5 引入的特性,用于为代码添加元数据。
内置注解
@Override
java
public class Parent {
public void method() {
System.out.println("父类方法");
}
}
public class Child extends Parent {
@Override // 明确表示这是重写方法
public void method() {
System.out.println("子类方法");
}
}@Deprecated
java
@Deprecated // 标记为已废弃
public class OldClass {
@Deprecated // 标记方法为已废弃
public void oldMethod() {
// 旧方法
}
}
// 使用时会警告
OldClass obj = new OldClass();
obj.oldMethod(); // 编译警告@SuppressWarnings
java
@SuppressWarnings("unchecked") // 抑制警告
public void method() {
List list = new ArrayList(); // 不会警告
list.add("item");
}自定义注解
java
// 定义注解
@Target(ElementType.METHOD) // 只能用于方法
@Retention(RetentionPolicy.RUNTIME) // 运行时保留
public @interface MyAnnotation {
String value() default "default";
int count() default 0;
}
// 使用注解
public class MyClass {
@MyAnnotation(value = "test", count = 5)
public void method() {
// 方法体
}
}注解元素
java
// 定义注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Author {
String name();
String email();
String date();
}
// 使用注解
public class MyClass {
@Author(name = "张三", email = "zhangsan@example.com", date = "2024-01-01")
public void method() {
// 方法体
}
}元注解
@Target
java
@Target(ElementType.METHOD) // 只能用于方法
public @interface MethodAnnotation { }
@Target({ElementType.METHOD, ElementType.FIELD}) // 可用于方法和字段
public @interface MethodOrFieldAnnotation { }@Retention
java
@Retention(RetentionPolicy.SOURCE) // 编译时丢弃
@Retention(RetentionPolicy.CLASS) // 类加载时丢弃
@Retention(RetentionPolicy.RUNTIME) // 运行时保留
public @interface MyAnnotation { }@Documented
java
@Documented // 包含在 JavaDoc 中
public @interface MyAnnotation { }@Inherited
java
@Inherited // 可以继承
public @interface MyAnnotation { }注解处理器
java
// 使用反射处理注解
public class AnnotationProcessor {
public static void processAnnotations(Class<?> clazz) {
// 获取类上的注解
if (clazz.isAnnotationPresent(Author.class)) {
Author author = clazz.getAnnotation(Author.class);
System.out.println("作者: " + author.name());
System.out.println("邮箱: " + author.email());
}
// 获取方法上的注解
Method[] methods = clazz.getDeclaredMethods();
for (Method method : methods) {
if (method.isAnnotationPresent(Author.class)) {
Author author = method.getAnnotation(Author.class);
System.out.println("方法: " + method.getName());
System.out.println("作者: " + author.name());
}
}
}
}完整示例
java
// 枚举示例
public enum Status {
PENDING("待处理"),
PROCESSING("处理中"),
COMPLETED("已完成"),
FAILED("失败");
private final String description;
Status(String description) {
this.description = description;
}
public String getDescription() {
return description;
}
}
// 注解示例
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Log {
String level() default "INFO";
String message() default "";
}
// 使用
public class Task {
private Status status = Status.PENDING;
@Log(level = "INFO", message = "开始处理任务")
public void start() {
status = Status.PROCESSING;
}
@Log(level = "INFO", message = "完成任务")
public void complete() {
status = Status.COMPLETED;
}
public Status getStatus() {
return status;
}
}
// 使用示例
public class EnumAnnotationExample {
public static void main(String[] args) {
// 枚举使用
Status status = Status.PENDING;
System.out.println(status.getDescription()); // 待处理
// 遍历枚举
for (Status s : Status.values()) {
System.out.println(s + ": " + s.getDescription());
}
// 注解处理
Task task = new Task();
processAnnotations(task.getClass());
}
private static void processAnnotations(Class<?> clazz) {
Method[] methods = clazz.getDeclaredMethods();
for (Method method : methods) {
if (method.isAnnotationPresent(Log.class)) {
Log log = method.getAnnotation(Log.class);
System.out.println("方法: " + method.getName());
System.out.println("日志级别: " + log.level());
System.out.println("日志消息: " + log.message());
}
}
}
}最佳实践
1. 枚举用于固定常量集
java
// ✅ 好的做法:使用枚举定义固定常量集
public enum Color {
RED, GREEN, BLUE
}
// ❌ 不好的做法:使用常量类
public class Color {
public static final String RED = "red";
public static final String GREEN = "green";
public static final String BLUE = "blue";
}2. 注解用于元数据
java
// ✅ 好的做法:使用注解添加元数据
@Deprecated
public void oldMethod() { }
// ✅ 好的做法:使用注解标记功能
@Transactional
public void saveData() { }下一步
掌握了枚举与注解后,可以继续学习:
- 多线程基础 - 学习多线程编程
- Java 8+ 新特性 - 学习 Java 新特性
💡 提示:枚举和注解是 Java 的重要特性,合理使用可以提高代码的可读性和可维护性
