我有一个看起来像这样的班
class Some {
private enum Inner {
}
}
我正在尝试在测试类的初始化块中找到Inner
类。
class SomeTest {
private static final Class<?> INNER_CLASS;
{
for (final Class<?> declaredClass: Some.class.getDeclaredClasses()) {
if (declaredClass.getSimpleName().equals("Inner")) {
INNER_CLASS = declaredClass;
// Variable `INNER_CLASS` might be assigned in loop
// break? return?
}
}
throw new ExceptionInitializerError("failed to find Inner.class");
}
}
编译器不喜欢这样,我找不到更好的方法。
我该如何解决?有什么好的模式吗?
答案 0 :(得分:3)
static
和instance
初始化块无法引发已检查的异常,因为无法声明这些块引发了这些异常。将ExceptionInitializerError
更改为RuntimeException
(或任何子类),然后将代码包装在try-catch
除了这里,您不会返回也不会中断,因此您总是会抛出异常。
至于“爆发”就好了,不要。您必须像编写void
方法的主体一样编写该块,但要限制您不能在任何地方使用return
。
答案 1 :(得分:3)
您的代码存在一些问题:
您的异常名称不正确。您尝试引发的异常称为ExceptionInInitializerError
而不是ExceptionInitializerError
。这是它不能编译的一个原因。
从不 1 抛出Error
或Error
的子类。
如果需要引发未经检查的异常,请引发RuntimeException
。还是更好,选择一些更具体的东西或定义并使用您自己的自定义(未经检查的)异常类。
(应该)应该是static
初始化程序块,而不是普通的(实例)初始化程序。您希望此代码一次……而不是每次创建SomeTest
实例时都执行。
要避免使用static
初始化程序块。基本上,它使您的应用程序失效了……因为封闭的类以及依赖于该类的任何类都无法初始化。
话虽如此,以下可能可能更合适:
static {
BlahType tmp = null;
label: {
for (...) {
if (...) {
tmp = ...;
break label;
}
}
throw new SomeException(...);
}
FINAL_VAR = tmp;
}
请注意,我们需要以确保确实分配给FINAL_VAR
的方式进行最终分配。 (我的猜测是这是您遇到编译错误的第二个原因。)
一种更自然的写上面的方法是:
static {
BlahType tmp = null;
for (...) {
if (...) {
tmp = ...;
break;
}
}
if (tmp == null) {
throw new SomeException(...);
}
FINAL_VAR = tmp;
}
1-可能太强了。我要说的是,抛出AssertionError
是可以的……假设您打算永远不会被捕获/恢复。在这种情况下,恢复仍然毫无意义。
答案 2 :(得分:0)
有几个问题:
检查一下:
class SomeTest {
private static final Class<?> INNER_CLASS;
static {
Class<?> foundClass = null;
for (final Class<?> declaredClass : Some.class.getDeclaredClasses()) {
if (declaredClass.getSimpleName().equals("Inner")) {
foundClass = declaredClass;
// Variable `INNER_CLASS` might be assigned in loop
// break? return?
}
}
INNER_CLASS = foundClass;
// throw new Exception("failed to find Inner.class");
}
}
答案 3 :(得分:0)
在最终分配之前使用中间变量。
class SomeTest {
private static final Class<?> INNER_CLASS;
static {
Class<?> innerClass = null;
for (final Class<?> declaredClass: Some.class.getDeclaredClasses()) {
if (declaredClass.getSimpleName().equals("Inner")) {
innerClass = declaredClass;
}
}
if (innerClass == null) {
throw new ExceptionInitializerError("failed to find Inner.class");
}
INNER_CLASS = innerClass;
}
}