代码之家  ›  专栏  ›  技术社区  ›  Alfonso

在Java中存在异常时将默认值分配给最终变量

  •  8
  • Alfonso  · 技术社区  · 15 年前

    为什么Java不允许在尝试块中设置值之后,在catch块中给最终变量赋值,即使在异常情况下不可能写入最终值。

    下面是一个演示问题的示例:

    public class FooBar {
    
        private final int foo;
    
        private FooBar() {
            try {
                int x = bla();
                foo = x; // In case of an exception this line is never reached
            } catch (Exception ex) {
                foo = 0; // But the compiler complains
                         // that foo might have been initialized
            }
        }
    
        private int bla() { // You can use any of the lines below, neither works
            // throw new RuntimeException();
            return 0;
        }
    }
    

    这个问题并不难解决,但我想理解为什么编译器不接受这个问题。

    提前感谢您提供任何信息!

    3 回复  |  直到 15 年前
        1
  •  7
  •   danben    15 年前
    try {
        int x = bla();
        foo = x; // In case of an exception this line is never reached
    } catch (Exception ex) {
        foo = 0; // But the compiler complains
                 // that foo might have been initialized
    }
    

    原因是编译器无法推断异常只能在 foo 是初始化的。这个例子是一个特殊情况,很明显这是正确的,但是要考虑:

    try {
        int x = bla();
        foo = x; // In case of an exception this line is never reached...or is it?
        callAnotherFunctionThatThrowsAnException();  // Now what?
    } catch (Exception ex) {
        foo = 0; // But the compiler complains
                 // that foo might have been initialized,
                 // and now it is correct.
    }
    

    编写一个编译器来处理这种非常具体的情况是一项艰巨的任务——很可能有很多这样的情况。

        2
  •  2
  •   Tom Hawtin - tackline    15 年前

    做个学究, Thread.stop(Throwable) 未能在try块分配后立即引发异常。

    但是,具有明确任务和相关术语的规则是非常复杂的。检查JLS。尝试添加更多的规则会使语言复杂化,并且不会带来显著的好处。

        3
  •  0
  •   lexicore    15 年前

    扔一个怎么样 Error ?