如何通过ClassLoader或类似机制实例化Enum类型? (我试图将所有内容保存在独立服务器应用程序的相同上下文类加载器下。)
我有类似的东西:
ClassLoader loader = new CustomClassLoader(parent, libDir);
Thread.currentThread().setContextClassLoader(loader);
// trouble area
Class<?> containerClass = loader.loadClass("com.somepackage.app.Name$SERVER");
我错误地认为只需加载Enum就足以启动它(它的私有构造函数包含启动方法调用和什么不是)。
执行上面的操作不会导致任何异常,但JVM只会在最后一行之后终止并且服务器无法启动。
显然在做:
containerClass.newInstance();
导致抛出异常。
答案 0 :(得分:4)
为了扩展我的评论,我认为你得到的最干净的是这样的:
public static <T extends Enum<T>> T loadEnum(ClassLoader loader, String classBinaryName, String instanceName) throws ClassNotFoundException {
@SuppressWarnings("unchecked")
Class<T> eClass = (Class<T>)loader.loadClass(classBinaryName);
return Enum.valueOf(eClass, instanceName);
}
实际上没有办法避免从Class<?>
到正确的枚举类型的未经检查的强制转换。但至少@SuppressWarnings
的范围有限。
进一步检查后,实际上有一种更简单的方法可以实现您的需求,而无需知道实例的名称且没有警告:
Class<?> containerClass = loader.loadClass("com.somepackage.app.Name");
containerClass.getEnumConstants()
答案 1 :(得分:0)
加载枚举不会导致它初始化。您必须通过字段引用或方法引用来引用它。因此,即使像Name name = Name.SERVER;
或Name.SERVER.name();
这样的简单陈述也可以解决问题。
请参阅Java虚拟机规范的第5.5 Initialization章中的5. Loading, Linking, and Initializing部分。