有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java是“错误:变量a可能未初始化”在这个if构造中真的有必要吗?

我如何告诉Java,我不需要初始化a就可以有一个工作程序,并且不给我一个错误

int a;
boolean b = true;
while (true) {
   if (b == false) {
       System.out.print(a);
       break;
   } else {
       b = false;
       a = 5;
   }
}

如果我不能,有什么原因可以解释为什么编译器是这样设计的吗

设计这样的编译器容易吗?还是这是一种确保我重新构造代码的机制

这与this one的问题不同


共 (1) 个答案

  1. # 1 楼答案

    Is 'error: variable a might not have been initialized' really necessary in this if construct?

    是的,这是必要的。Java语言规范需要它。这将在JLS 16 - Definite Assignment中介绍

    "Each local variable (§14.4) and every blank final field (§4.12.4, §8.3.1.2) must have a definitely assigned value when any access of its value occurs."


    How do I tell Java that I don't need to initialize a to have a working program and to not give me an error?

    你不能这么说。你需要初始化变量。。。或者重组代码


    And if I can't, is there a reason why this is the way the compiler was designed?

    因为Java编译器必须实现规范,否则它就不是一个合适的Java编译器。说明书上说这是一个错误

    真正的问题是为什么规范会这么说。答案是,编译器编写人员不必被迫在所有Java编译器中包含困难的定理证明代码

    • 在你给出的例子中,程序员很明显,变量总是会被初始化的。然而,编译器需要验证它。它需要绝对确定,因为未初始化的变量会有未定义的行为

    • 自动(无方向)验证是一项复杂的任务。复杂意味着需要编写更多的(编译器)代码、更多(编译器)错误等等

    • 这种技术的“最新水平”不足以对复杂的Java代码进行这种分析

    • 在某些(理论)情况下,验证变量是否初始化在数学上是不可能的

    所以。。。明智地指定Java语言的人把这一点推回给了程序员。根据JLS中规定的规则,您需要编写代码,以便在使用前明确分配变量

    还有第二个原因。假设JLS确实允许Java编译器接受

       System.out.print(a);
    

    当且仅当它能够满足a是(总是)预先初始化的。现在考虑两个不同的人编写的java编译器(或者在不同时间的同一个人)来实现JLS的相同版本。p>

    • 编译器C1可以计算出a始终是初始化的,并且表示程序是有效的

    • 编译器C2无法确定a始终是初始化的,并表示该程序无效

    我们现在有两个Java编译器,它们表面上实现了相同版本的JLS,但在示例程序(上面)是否有效方面存在分歧。这根本站不住脚


    让事情进一步复杂化的是,我怀疑当JVM验证刚刚加载的字节码时,也必须进行类似于“确定分配”检查的操作。因此,对JLS明确分配规则的更改将波及JVM,并可能影响直接编译/生成JVM字节码的其他编程语言和工具的JVM平台的行为