[英]How to break out initialization block?
I have a class looks like this 我上课看起来像这样
class Some {
private enum Inner {
}
}
And I'm trying to find the Inner
class in a initialization block of my test class. 我正在尝试在测试类的初始化块中找到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");
}
}
The compiler doesn't like this and I couldn't find any better way. 编译器不喜欢这样,我找不到更好的方法。
How can I solve this? 我该如何解决? Is there any good pattern for this? 有什么好的模式吗?
static
and instance
initialization block cannot throw checked exceptions as there is no way to declare that those blocks throws these execeptions. static
和instance
初始化块无法引发检查的异常,因为无法声明这些块引发了这些异常。 Change ExceptionInitializerError
to RuntimeException
(or any subclass) and wrap your code in try-catch
将ExceptionInitializerError
更改为RuntimeException
(或任何子类),然后将代码包装在try-catch
Besides here, you are not returning nor breaking thus you always throw exception. 除了这里,您不会返回也不会中断,因此您总是会抛出异常。
As for "breaking out" well simply yo dont. 至于“爆发”好吧,你不要。 You have to write that block as it would be body of void
method but with the restriction that you cannot use return
anywhere. 您必须编写该块,因为它会成为void
方法的主体,但有一个限制,即您不能在任何地方使用return
。
There are a few problems with your code: 您的代码存在一些问题:
You have the exception name incorrect. 您的异常名称不正确。 The exception you are trying to throw is called ExceptionInInitializerError
not ExceptionInitializerError
. 您尝试引发的ExceptionInInitializerError
称为ExceptionInInitializerError
而不是ExceptionInitializerError
。 That is one reason why it won't compile. 这就是为什么它无法编译的原因之一。
Never 1 throw Error
or subclasses of Error
. 从不1掷Error
或子类Error
。
If you need to throw an unchecked exception, throw RuntimeException
. 如果需要抛出未经检查的异常,则抛出RuntimeException
。 Or better still, pick something more specific or define and use your own custom (unchecked) exception class. 还是更好,选择一些更具体的东西,或者定义并使用您自己的自定义(未经检查)异常类。
This should (probably) be a static
initializer block, not a plain (instance) initializer. 这(可能)应该是static
初始化程序块,而不是普通的(实例)初始化程序。 You want this code to be executed once ... not every time a SomeTest
instance is created. 您希望此代码一次执行,而不是每次创建SomeTest
实例时都执行一次 。
Bailing out of a static
initializer block is something you want to avoid. 要避免从static
初始值设定项块中释放出来。 It basically leaves you with a dead application ... because the enclosing class and any classes that depend on it become uninitializable. 从根本上来说,这会让您的应用程序失效……因为封闭的类以及依赖于该类的任何类都无法初始化。
Having said that, the following might be a more appropriate structure: 话虽如此,以下可能是一个更合适的结构:
static {
BlahType tmp = null;
label: {
for (...) {
if (...) {
tmp = ...;
break label;
}
}
throw new SomeException(...);
}
FINAL_VAR = tmp;
}
Note that we need to do the final assignment to FINAL_VAR
in a way that ensures that it is definitely assigned. 请注意,我们需要以确保已明确分配的方式对FINAL_VAR
进行最终分配。 (My guess is that is a second reason you were getting compilation errors.) (我的猜测是这是您遇到编译错误的第二个原因。)
And a more natural way to write the above would be: 编写上面内容的更自然的方法是:
static {
BlahType tmp = null;
for (...) {
if (...) {
tmp = ...;
break;
}
}
if (tmp == null) {
throw new SomeException(...);
}
FINAL_VAR = tmp;
}
1 - Maybe a bit too strong. 1-可能太强了。 I would say that throwing AssertionError
is OK ... assuming that you intend for it never be caught / recovered from. 我要说的是,抛出AssertionError
是可以的...假设您从未打算将其捕获/恢复。 In this case, recovery is moot anyway. 在这种情况下,无论如何都没有恢复的余地。
There are couple of issues: 有几个问题:
Check this out: 看一下这个:
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");
}
}
Use intermediate variable before final assignment. 在最终分配之前使用中间变量。
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;
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.