如何获取sealed类所有许可子类的实例集合?
Java sealed类实现类似Enum.values()的子类实例获取方法
你目前的实现思路是可行的,但存在几个可优化的点:
- 方法类型错误:当前
values()是实例方法,调用时需要先持有Color类的实例,不符合工具方法的使用习惯,应该改为静态方法 - 实例重复创建:每次调用方法都会通过反射新建所有子类的实例,无法保证实例全局唯一,和
Enum.values()返回固定实例集合的预期不符 - 异常处理不合理:直接静默吞噬所有反射异常,排查子类构造/实例获取失败问题时难度很高
- 性能损耗:每次调用都执行反射操作,高并发场景下性能表现不佳
针对不同的业务场景,给出两种优化方案:
场景1:所有许可子类均为单例(最贴合Enum使用场景)
假设所有子类都遵循单例规范,比如是枚举类,或约定公开静态INSTANCE字段持有唯一实例,优化后代码如下:
import java.util.Arrays; import java.util.List; abstract sealed class Color permits Green, Red { // 缓存实例集合,类加载时仅初始化一次 private static final List<Color> VALUES = initValues(); // 对外暴露静态方法,和Enum.values()用法完全一致 public static List<Color> values() { return VALUES; } private static List<Color> initValues() { return Arrays.stream(Color.class.getPermittedSubclasses()) .map(subclass -> { try { // 优先处理枚举子类的情况 if (subclass.isEnum()) { return (Color) subclass.getEnumConstants()[0]; } // 处理自定义单例子类,约定有公开静态INSTANCE字段 return (Color) subclass.getField("INSTANCE").get(null); } catch (ReflectiveOperationException e) { // 初始化阶段直接抛出异常,避免后续运行时才发现配置问题 throw new RuntimeException("无法获取%s类的单例实例".formatted(subclass.getName()), e); } }) .toList(); } } // 示例自定义单例子类实现 final class Green extends Color { public static final Green INSTANCE = new Green(); private Green() {} } // 示例枚举子类实现 enum Red extends Color { INSTANCE }
场景2:允许每次调用返回新实例
如果业务场景允许每次调用values()返回全新的子类实例,可以在现有实现基础上调整为静态方法、优化异常处理即可:
import java.util.Arrays; import java.util.List; import java.util.stream.Stream; abstract sealed class Color permits Green, Red { public static List<Color> values() { return Arrays.stream(Color.class.getPermittedSubclasses()) .flatMap(subclass -> { try { return Stream.of(subclass.getDeclaredConstructor().newInstance()); } catch (ReflectiveOperationException e) { throw new RuntimeException("无法实例化%s类".formatted(subclass.getName()), e); } }) .toList(); } }
内容的提问来源于stack exchange,提问作者Nolequen
相关产品推荐
相关产品推荐

