16

例如:

int anInt = null;

编译时失败,但

public static void main(String[] args) {
  for (int i = 0; i < 10; i++) {
    System.out.println("" + getSomeVal());
  }
}
public static int getSomeVal() {
   return new Random().nextBoolean() ? 1 : null;
}

(通常)在运行时失败。试图返回 justnull也会导致编译错误,所以我认为有多个路径会导致编译器推断出null可能是自动装箱的int?为什么 javac 不能编译这两种情况并出现相同的错误?

4

3 回答 3

20

在第一种情况下,编译器知道您正在尝试拆箱null.

在第二种情况下,条件表达式的类型是Integer,因此您实际上是在编写:

Integer tmp = new Random().nextBoolean() ? 1 : null;
return (int) tmp;

...所以拆箱不会发生在常量表达式上,编译器会允许它。

int如果您通过取消装箱将其更改为强制条件表达式为类型它将失败:

// Compile-time failure
return new Random().nextBoolean() ? 1 : (int) null;
于 2012-08-10T08:23:42.487 回答
2

装箱部分隐藏了基元和相应的包装对象之间的区别,但并没有消除它。

拳击不会改变两个区别:

  • 对象可以为空,而基元不能
  • 对象既有状态又有身份,而原语只有状态(值)

有时,这些差异可能会在使用拳击时引起问题。

要记住的几点:

  • 小心空值。自动拆箱 null 对象将导致NullPointerException.
  • 比较项目==并且equals必须小心进行。
于 2012-08-10T08:25:01.227 回答
1

您不能将 null 分配给 int

    int anInt = null;

Java 允许这样做,因为您没有将 null 分配给 int

    System.out.println("" + getSomeVal()); //null was just converted to a srting and was printed

如果你执行这个,你会得到错误

    int anInt = getSomeVal();
于 2012-08-10T08:33:59.973 回答