【问题标题】:Why the code that the compiler approves but cannot be run by JVM? [duplicate]为什么编译器认可但JVM不能运行的代码? [复制]
【发布时间】:2021-08-19 21:32:39
【问题描述】:

这是一个 Head First Java 练习。练习是关于自动装箱(包装和展开)。

为什么编译器同意将 Integer i(默认值为 null)分配给 int j(默认值为 0)?

当我运行它时,它显示:“无法调用“java.lang.Integer.intValue()”,因为“this.i”为空”

public class TestBox {
   Integer i; 
   int j; 

   public static void main(String[] args) {
      TestBox t = new TestBox(); 
      t.go(); 
   }

   public void go() {
      j = i; 
      System.out.println(j); 
      System.out.println(i);
   }
}

【问题讨论】:

  • 您的程序正在由 JVM 运行。它只是在运行时遇到错误。并非所有潜在错误都可以在编译时发现。运行时发生的错误是你必须忍受的。
  • 编译器在编译时不知道任何值。通常允许将Integer 分配给int,因此编译器不会失败。在运行期间,程序会遇到问题,因为它无法将Integernull 值分配给int。有关在编译时和/或运行时可能发现的错误的更多详细信息,请查看@OHGODSPIDERS 参考。
  • 编译器不关心默认值。它不跟踪值是什么或可能是什么。是的,自动拆箱是 NPE 可能发生的机会。呼叫i.toString() 也是如此。为了让编译器能够真正防止此类问题,您需要在类型系统中内置 nullity。例如IntegerInteger?(可空整数),like Kotlin has
  • 谢谢大家!!!

标签: java jvm autoboxing javacompiler


【解决方案1】:

Integer i对象引用的声明。对象引用被隐式初始化为null。因此,您会在运行时获得NullPointerException

编译器不会抱怨,因为变量既没有声明private 也没有声明final,所以它可能在运行时从这个类的外部由尚未编写的代码初始化。因此编译器无法将其检测为错误或警告。

因此,您应该限制变量的可见性。如果添加private 关键字,编译器会发出警告。

【讨论】:

    【解决方案2】:

    java中有两种异常:

    1. 运行时异常 - 发生在运行时
    2. 编译时异常 - 在编译时发生

    您的程序抛出的异常是运行时异常,这就是您的程序编译成功但由于运行时异常而失败的原因。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-31
      • 2015-10-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多