Java中枚举的使用
枚举(Enumeration)类型是Java提供的一种特殊的类,合理使用可以明确概念、简化编码、减少bug。由于不了解枚举类的特性,许多开发者将枚举当成了常量来用,远远没有发挥出枚举的威力。
- 如何定义枚举 我们可以定义一个名为MediaPlatform的枚举,包括抖音、小红书、微博、知乎、B站等枚举值。并且每个枚举值可以视为特殊的类,可以拥有自己的方法和属性。【重点】
public enum MediaPlatform {
DOUYIN("<https://www.douyin.com/>"),
XIAOHONGSHU("<https://www.xiaohongshu.com/>"),
WEIBO("<https://www.weibo.com/>"),
ZHIHU("<https://www.zhihu.com/>"),
BILIBILI("<https://www.bilibili.com/>");
private String url;
MediaPlatform(String url) {
this.url = url;
}
public String getUrl() {
return url;
}
public boolean supportsPlugin() {
switch (this) {
case DOUYIN:
case XIAOHONGSHU:
return true;
default:
return false;
}
}
}
- 如何通过一个值获取枚举 我们可以通过枚举的name()方法获取枚举的名称,然后使用Enum的valueOf方法根据名称获取枚举对象。
public MediaPlatform getMediaPlatform(String name) {
return MediaPlatform.valueOf(name);
}
- 如何在switch中直接使用枚举对象进行判断 在Java的switch语句中,我们可以直接使用枚举对象进行判断。
public void checkMediaPlatform(MediaPlatform platform) {
switch (platform) {
case DOUYIN:
System.out.println("This is Douyin");
break;
case XIAOHONGSHU:
System.out.println("This is Xiaohongshu");
break;
// ...
default:
System.out.println("Unknown media platform");
}
}
- 如果枚举作为DTO对象的一个字段时,如何从数据库和Model之间映射 在使用JPA或者MyBatis等ORM框架时,我们可以直接使用枚举作为实体类的字段。只需要在字段上使用@Enumerated注解指定映射方式即可。
我们项目使用了MyBatisPlus,可以安全使用Enumerated注解。 使用该注解时必须保证枚举字面量和数据库值一致。
@Entity
public class User {
// ...
@Enumerated(EnumType.STRING)
private MediaPlatform mediaPlatform;
// ...
}
如果数据库存储的是枚举的名称,应使用EnumType.STRING。如果数据库存储的是枚举的顺序,应使用EnumType.ORDINAL。
- 如果枚举字段是从controller直接传入的,如何映射到Model 通常,当我们使用Spring MVC时,可以直接在Controller方法的参数上使用@PathVariable或@RequestParam注解,Spring会自动进行类型转换。
@RequestMapping("/user/{mediaPlatform}")
public String
getUser(@PathVariable MediaPlatform mediaPlatform) {
// ...
}
在此示例中,如果URL中的mediaPlatform是枚举的名称,Spring将自动将其转换为对应的枚举对象。
使用RequestBody时, 枚举对象可以作为对象的字段从外部注入。例如我们有一个枚举类型ScoutTermEnum接收淘号类型
public enum ScoutTermEnum {
BRAND("brand"),
CONTENT("content");
private String value;
ScoutTermEnum(String value) {
this.value = value;
}
@JsonValue //NOTE:枚举字面量和值不一致时必须添加该注解转换
public String toValue() {
return value;
}
}
并定义了模型传输对象ScoutVO
public class ScoutVO {
private List<String> keywords;
private ScoutTermEnum type;
//...
}
在控制器方法中可以像使用普通模型传输对象一样使用枚举:
@PostMapping("/{platform}/scout/estimate-size")
public R<Map<String, Integer>> scoutInfluencersSize(@PathVariable("platform") Platform platform, @RequestBody ScoutVO scoutVO) {
ScoutTermEnum type = scoutVO.getType();
return null;//todo-replace real obj
}
调用时传入{”type”:”brand”}, 例如:
curl --location --request POST 'http://lh:8080/xhs/scout/estimate-size' \
--header 'Content-Type: application/json' \
--data-raw '{
"keywords": [
"a",
"b"
],
"type": "brand"
}'
控制器方法将自动转换为ScoutTermEnum对象BRAND。
如果传入的值无法转换为枚举对象,Spring将抛出参数异常。