<think>在Java枚举中,括号内的内容实际上是传递给枚举常量的构造函数的参数。枚举常量可以带有参数,这些参数在枚举常量被创建时传递给其构造函数。
括号内可以写:
1. 基本数据类型(如int, double等)
2. 字符串
3. 其他对象(需要与构造函数参数类型匹配)
4. 多个参数,用逗号分隔
需要注意的是:
- 枚举常量的参数必须与枚举类中定义的构造函数参数匹配。
- 枚举的构造函数必须是私有的(private),或者不写访问修饰符(默认private),不能是public或protected。
下面是一个具体的例子,展示枚举常量括号内可以写什么:</think>### Java 枚举类型参数详解
在 Java 枚举中,括号内的内容实际上是传递给枚举构造函数的参数。这些参数允许你为每个枚举常量关联特定的数据值,使枚举更加灵活和强大。
#### 枚举常量括号内可以包含的内容:
1. **基本数据类型**:int, double, boolean 等
2. **字符串**:String 类型
3. **对象**:任何自定义对象类型
4. **其他枚举类型**:其他枚举的实例
5. **数组**:基本类型或对象数组
6. **表达式**:常量表达式或简单计算
7. **null**(谨慎使用)
#### 完整代码示例
```java
import java.time.LocalDate;
// 基础类型和字符串
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");
private final int code;
private final String description;
HttpStatus(int code, String description) {
this.code = code;
this.description = description;
}
public int getCode() { return code; }
public String getDescription() { return description; }
}
// 包含对象和数组
enum UserRole {
ADMIN("Administrator", new String[]{"ALL_PERMISSIONS"}),
EDITOR("Content Editor", new String[]{"CREATE", "EDIT"}),
VIEWER("Read-only User", new String[]{"READ"}); // 括号内是字符串和字符串数组
private final String displayName;
private final String[] permissions;
UserRole(String displayName, String[] permissions) {
this.displayName = displayName;
this.permissions = permissions;
}
}
// 包含其他枚举和表达式
enum OrderStatus {
PENDING(Priority.NORMAL, LocalDate.now().plusDays(3)), // 使用表达式
PROCESSING(Priority.HIGH, null),
SHIPPED(Priority.LOW, LocalDate.now().plusDays(7)),
DELIVERED(Priority.LOW, null); // 包含其他枚举和日期对象
private final Priority priority;
private final LocalDate expectedDate;
OrderStatus(Priority priority, LocalDate expectedDate) {
this.priority = priority;
this.expectedDate = expectedDate;
}
}
enum Priority { HIGH, NORMAL, LOW }
// 包含自定义对象
class GeoLocation {
private final double lat;
private final double lon;
public GeoLocation(double lat, double lon) {
this.lat = lat;
this.lon = lon;
}
@Override
public String toString() {
return String.format("(%.4f, %.4f)", lat, lon);
}
}
enum City {
NEW_YORK("NYC", new GeoLocation(40.7128, -74.0060)), // 自定义对象
LONDON("LDN", new GeoLocation(51.5074, -0.1278)),
TOKYO("TYO", new GeoLocation(35.6762, 139.6503));
private final String code;
private final GeoLocation location;
City(String code, GeoLocation location) {
this.code = code;
this.location = location;
}
}
```
#### 使用示例
```java
public class EnumParameterDemo {
public static void main(String[] args) {
// 使用带参数的枚举
System.out.println("HTTP 状态码:");
System.out.println(HttpStatus.NOT_FOUND.getCode() + ": " +
HttpStatus.NOT_FOUND.getDescription());
// 使用带数组的枚举
System.out.println("\n用户权限:");
for (String perm : UserRole.EDITOR.permissions) {
System.out.println("- " + perm);
}
// 使用带其他枚举的枚举
System.out.println("\n订单状态:");
System.out.println("Shipping priority: " +
OrderStatus.SHIPPED.priority);
// 使用带自定义对象的枚举
System.out.println("\n城市坐标:");
System.out.println(City.TOKYO + " location: " +
City.TOKYO.location);
}
}
```
#### 参数使用规则和最佳实践:
1. **参数顺序必须匹配构造函数**:
```java
// 正确
OK(200, "OK")
// 错误 - 参数顺序不匹配
// OK("OK", 200)
```
2. **参数类型必须匹配构造函数**:
```java
// 构造函数: HttpStatus(int, String)
// 正确
NOT_FOUND(404, "Not Found")
// 错误 - 类型不匹配
// NOT_FOUND("404", "Not Found")
```
3. **参数数量必须匹配**:
```java
// 构造函数需要2个参数
// 错误 - 参数不足
// NOT_FOUND(404)
// 错误 - 参数过多
// NOT_FOUND(404, "Not Found", "Resource missing")
```
4. **使用常量表达式**:
```java
// 正确 - 使用常量表达式
MAX_VALUE(100 * 2)
// 错误 - 不能使用非常量
// RANDOM_VALUE(new Random().nextInt())
```
5. **避免复杂逻辑**:
构造函数应保持简单,避免复杂业务逻辑
6. **空值处理**:
如果允许 null 值,应在文档中明确说明
```java
DELIVERED(Priority.LOW, null) // 明确表示无预期日期
```
7. **不可变原则**:
枚举字段应该声明为 final,确保不可变性
#### 高级用法:枚举中的抽象方法
```java
enum Operation {
PLUS("+") {
public double apply(double x, double y) { return x + y; }
},
MINUS("-") {
public double apply(double x, double y) { return x - y; }
},
TIMES("*") {
public double apply(double x, double y) { return x * y; }
},
DIVIDE("/") {
public double apply(double x, double y) { return x / y; }
};
private final String symbol;
Operation(String symbol) {
this.symbol = symbol;
}
public abstract double apply(double x, double y);
@Override
public String toString() {
return symbol;
}
}
```