Java8 PropertyEditorManager如何注册支持索引输入的自定义Enum编辑器
根本原因
- 你调用
PropertyEditorManager.findEditor()时传入的是具体枚举子类的Class对象(比如自定义的OrderStatusEnum.class),而非Enum.class。PropertyEditorManager的匹配逻辑是精确匹配目标类,不会自动继承父类的注册配置,因此你给Enum.class注册的编辑器不会对任何实际使用的枚举子类生效。 - JDK内置的
EnumEditor是PropertyEditorManager在未找到对应枚举类的显式注册时,通过默认搜索路径sun.beans.editors自动匹配到的兜底实现,因此每次查找具体枚举类的编辑器都会返回系统内置版本。
解决方案
方案1:自定义查找逻辑(最推荐,无侵入)
不需要修改编辑器注册逻辑,只需要在你原有调用findEditor的位置增加一层枚举类型判断,手动实例化自定义编辑器即可:
final Class<?> targetType = descriptor.getPropertyType(); final PropertyEditor editor; if (Enum.class.isAssignableFrom(targetType)) { // 所有枚举类型直接使用自定义编辑器 editor = new IndexedEnumEditor((Class<? extends Enum<?>>) targetType); } else { // 非枚举类型走原有查找逻辑 editor = PropertyEditorManager.findEditor(targetType); }
该方案无需硬编码任何具体枚举类,所有枚举都会自动适配自定义实现,性能更高,也不会影响JDK其他内置编辑器的正常使用,完全兼容Java 8环境。
方案2:修改编辑器搜索路径(可选)
如果不想改动原有查找代码,可以调整PropertyEditorManager的搜索优先级,让它优先加载你自定义的编辑器:
- 把你的
IndexedEnumEditor类重命名为EnumEditor,保持在com.csa.model.bean.editor包下 - 在静态注册代码块中增加以下逻辑:
// 调整编辑器搜索路径,优先使用自定义包下的实现,移除sun内置包的优先级 List<String> searchPaths = new ArrayList<>(Arrays.asList(PropertyEditorManager.getEditorSearchPath())); searchPaths.remove("sun.beans.editors"); searchPaths.add(0, "com.csa.model.bean.editor"); PropertyEditorManager.setEditorSearchPath(searchPaths.toArray(new String[0]));
注意该方案会导致JDK其他内置编辑器(比如IntegerEditor、BooleanEditor等)无法被自动搜索到,你需要把所有需要用到的内置编辑器都显式注册一遍,维护成本更高。
内容的提问来源于stack exchange,提问作者ManoDestra
相关产品推荐
相关产品推荐

