禁用 IntelliJ 编译器错误



我收到"变量TMP_1可能尚未初始化"错误。 这是代码片段:

10  case 1000:
11       Double TMP_1 = len(T$);
12       I = 1d;
13  case 1001:
14       if (I.compareTo(TMP_1) > 0) {

第 14 行报告错误。 在我的程序中,如果不执行案例 1000 的代码块,就不可能到达案例 1001。显然Intellij无法弄清楚这一点。 如何禁用此错误? 我宁愿使用空指针异常进行更改。

源代码是由我编写的编译器生成的(源语言是古老的BASIC(。将任务重新安置在第11行将非常困难。

编辑 - 请参阅下面的机械蜗牛解释。 这根本不是编译器错误;这是一个简单的程序错误。 问题是我模拟 BASIC 的 GOTO 语句的方式要求我离开 switch 语句。 当我这样做时,tmp 变量超出了范围。

最终编辑 - 我更改了代码生成器以完全删除 TMP 变量。

case 2026:
          V = (asc(V$)) - (asc(" "));
          dataCursor.restore();
          for (J = 1d; J <= ((V * 8d) * 10d); J++) {
               X = dataCursor.read();
          }

以前,for 循环中的算术是使用 2026 标签之前设置的 tmp 变量完成的。 现在因为没有,所以没有问题。

Java 编译器不够聪明,无法证明在执行初始化变量的代码之前,您正在打开的变量永远不会1001。请记住,Java 变量声明是完全静态的;根据设计,Java只允许你的变量以有意义的方式使用,即在使用前初始化。对于一般代码,证明这种情况的发生等效于解决停止问题。(对于编译器所知,表达式I.compareTo(TMP_1) > 0可能是无意义的,因为它引用了一个不存在的变量。(更准确地说,变量是在 switch 语句的主体范围内声明的,但如果跳到标签case 1001:,初始化它的代码将不会执行。

不允许将此错误转换为警告;这是静态语言的缺点之一。特别是,Java 语言规范第 16 章要求:

对于局部变量 [...] x 的每次访问,必须在访问之前明确分配 x,否则会发生编译时错误。

并且变量在访问之前不是"明确分配"(如规范中所定义(。IntelliJ使用Java编译器(通常是javac(编译您的代码。由于你试图做的事情是标准所要求的错误,所以你想要的是不可能的(除了编辑编译器,然后它就不再是Java了(。

解决方法

相反,只需在周围的范围内声明变量,并将其初始化为虚拟值。例如:

Double TMP_1 = null;
while(exitVar) {
    switch(lblToGoTo) {
        ...
        case 1000:
            TMP_1 = len(T$);
            I = 1d;
        case 1001:
            if (I.compareTo(TMP_1) > 0) { ... }
        ...
    }
}

最新更新