java - 'error: variable a might not have been initialized' 在这个 if 构造中真的有必要吗?

标签 java if-statement

我如何告诉 Java 我不需要初始化 a 来拥有一个可以工作的程序并且不会给我一个错误?

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

如果我不能,是否有理由这样做编译器的设计方式?

设计这样的编译器是否容易,或者这是确保我重组代码的机制?

这与 this one 不是同一个问题

最佳答案

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?

你不能告诉Java这一点。您需要初始化变量...或重构代码。

<小时/>

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。

  • 编译器 C1 可以判断出 a 始终已初始化,并表明该程序是有效的。

  • 编译器 C2 无法识别出 a 始终已初始化,并表示该程序无效。

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

<小时/>

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

关于java - 'error: variable a might not have been initialized' 在这个 if 构造中真的有必要吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52564375/

相关文章:

if-statement - "If with a short statement"有什么好处

javascript - jQuery 中 if(something.length) 的含义

image - 如何在 Swift 中更改 IBAction UIButton 的图像?

java - 将子类转换为父类(super class)实现的子接口(interface)

java - 如何在 Web 服务 Java EE 中使用 EJB

java - 即使一个 bean 在运行时出现错误,也确保 Spring 应用程序的其余部分运行

java - 如何让ScheduledThreadPool报错?

java - 反射(reflection)Java

c# - 动态 if 语句?

if-statement - IF 如何影响复杂性?