Java 如何突破初始化块?
我有一节课看起来像这样Java 如何突破初始化块?,java,initialization-block,Java,Initialization Block,我有一节课看起来像这样 class Some { private enum Inner { } } 我试图在测试类的初始化块中找到内部类 class SomeTest { private static final Class<?> INNER_CLASS; { for (final Class<?> declaredClass: Some.class.getDeclaredClasses()) {
class Some {
private enum 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");
}
}
类测试{
私有静态final类内部_类;
{
for(最终类declaredClass:Some.Class.getDeclaredClass()){
if(declaredClass.getSimpleName().equals(“内部”)){
内部类=申报类;
//变量'internal_CLASS'可能在循环中赋值
//休息?回来?
}
}
抛出新的ExceptionInitializeError(“未能找到内部.class”);
}
}
编译器不喜欢这样,我找不到更好的方法
我怎样才能解决这个问题?有什么好的模式吗?静态
和实例
初始化块不能抛出选中的异常,因为无法声明这些块抛出这些异常。将exceptioninitializeerror
更改为RuntimeException
(或任何子类),并将代码包装到try catch
除此之外,您不会返回也不会中断,因此您总是抛出异常
至于“爆发”,那你就别想了。您必须编写该块,因为它是void
方法的主体,但有一个限制,即您不能在任何地方使用return
。有两个问题:
异常总是被抛出
您正在为循环中的最后一个变量赋值
初始化块不是静态的,并分配给静态最终变量
看看这个:
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");
}
}
类测试{
私有静态final类内部_类;
静止的{
类foundClass=null;
for(最终类declaredClass:Some.Class.getDeclaredClass()){
if(declaredClass.getSimpleName().equals(“内部”)){
foundClass=declaredClass;
//变量'internal_CLASS'可能在循环中赋值
//休息?回来?
}
}
内部_类=foundClass;
//抛出新异常(“未能找到内部.class”);
}
}
在最终赋值之前使用中间变量
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;
}
}
类测试{
私有静态final类内部_类;
静止的{
类innerClass=null;
for(最终类declaredClass:Some.Class.getDeclaredClass()){
if(declaredClass.getSimpleName().equals(“内部”)){
innerClass=declaredClass;
}
}
if(innerClass==null){
抛出新的ExceptionInitializeError(“未能找到内部.class”);
}
内部类=内部类;
}
}
您的代码有几个问题:
您的异常名称不正确。您试图抛出的异常称为exceptionininitializerror
而不是exceptioninitializerror
。这就是它无法编译的原因之一
从不抛出错误
或错误
的子类
如果需要抛出未经检查的异常,请抛出RuntimeException
。或者更好的是,选择更具体的内容,或者定义并使用您自己的自定义(未选中)异常类
这应该(可能)是一个静态初始值设定项块,而不是一个普通的(实例)初始值设定项。您希望此代码执行一次。。。并非每次创建SomeTest
实例时
退出静态
初始值设定项块是您希望避免的事情。它基本上给你留下了一个死气沉沉的应用程序。。。因为封闭类和依赖它的任何类都变得不可初始化
话虽如此,以下结构可能更合适:
static {
BlahType tmp = null;
label: {
for (...) {
if (...) {
tmp = ...;
break label;
}
}
throw new SomeException(...);
}
FINAL_VAR = tmp;
}
请注意,我们需要对final\u VAR
进行最终赋值,以确保它被明确赋值。(我猜这是您出现编译错误的第二个原因。)
写上述内容的更自然的方式是:
static {
BlahType tmp = null;
for (...) {
if (...) {
tmp = ...;
break;
}
}
if (tmp == null) {
throw new SomeException(...);
}
FINAL_VAR = tmp;
}
1-可能有点太强了。我想说抛出断言错误是可以的。。。假设你的意图是永远不会被抓住/找回。在这种情况下,恢复是没有意义的。编译器对此有什么不喜欢的?我没有看到return语句,这意味着您的ExceptionInitializeError
将始终被抛出。它不应该是静态初始值设定项块吗?初始化块不是静态的,并且分配给一个语义有效的静态变量。分配给final在非静态块中无效。但需要检查。最后的变量是不同的故事。只需澄清第3点,即您所谈论的是静态最终结果。