有帮助吗?

解决方案

这可能似乎直觉到异常可以在一个= 1行发生,但可能发生JVM错误。因此,留下变量a初始化。因此,编译器错误使得完整意义上的。这是的你提到的晦涩的运行时错误。但是,我认为,一个OutOfMemoryError是远离晦涩的,应由开发商至少想过。此外,记住,树立的OutOfMemoryError在另一个线程和推堆内存使用过去的限制量的一个动作可能发生的状态是变量a的分配。

不管怎么说,因为你在看编译器的设计,我也假设你已经知道它是多么的愚蠢到在finally块返回值。

其他提示

Java语言规范要求在使用前的变量被分配。该JLS定义为被称为“定分配”规则的具体规则。所有的Java编译器需要坚持给他们。

JLS 16.2.15

  

V是最后块当且仅当V是try语句之前明确赋值之前明确赋值。

在另一个话,考虑到最后语句时,一个try-catch-finally语句分配内的try和catch语句块不考虑。

不用说,该规范是非常保守的在这里,但他们宁愿有规范是简单而位有限(认为规则已经复杂)比手下留情,但很难理解和推理。

编译器必须遵循以下明确赋值规则,让所有的编译器发出同样的错误。编译器不允许比JLS指定以抑制任何错误时执行任何额外的分析。

我相信这只是由于一个try-catch-终于关系的语义。从 Java语言规范

  

如果try块的执行   正常完成,那么最终   执行块...

     

如果try块的执行   完成突然因为一抛   一值V ...

     

如果try块的执行   突然完成任何其他   原因R,则最后块是   执行...

在最后一种情况似乎是最相关的。看来,finally块应该能正确执行,如果try块以任何理由突然结束。显然,如果try块分配结束前finally块将是无效的。不过,如你所说,这是不是特别容易。

这是非常有可能的javac需要,使毯假设异常可以在try块的任何地方出现,甚至在分配,以及因此最终可能会返回一个未初始化的变量。从理论上讲它可以做一个详细的分析,并发现,在所有的路径通过try块“一个”总是被成功初始化,但是这是一个大量的工作,几乎没有收益。

现在,如果有人正好可以指出在Java语言规范中的相关章节...

如果编译器不能确定发生在条件块

编译器错误,以下(后续) 语句将运行状

int i=5;int d;
if(i<10)
{system.out.println(d);}

如果所述条件语句是肯定的和不可疑代码不会像

达到不会发生编译器错误
int i;

if(true){}

else
{System.out.println(d);}

和如果所述条件语句肯定会发生,并且不可疑代码将像

达到将发生编译器错误
int i;
if(true)
{System.out.println(d);}
else{}

作为try块下此来它们遵循相同的规则。

我想Java编译器假设最坏的情况 - 没有保证在try块东西,甚至是由于某种原因执行。因此,它的抱怨是有效的。变量可能没有被初始化。

编译器只是被保守这里。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top