简体   繁体   English

为什么Java编译器有时允许取消装箱为空?

[英]Why does the Java compiler sometimes allow the unboxing of null?

For example: 例如:

int anInt = null;

fails at compile time but 在编译时失败但是

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;
}

fails (usually) at run time. 在运行时(通常)失败。 Trying to return just null will also result in a compile error, so I assume there is something about having multiple paths that causes the compiler to infer that null is potentially an autoboxed int ? 尝试返回null也会导致编译错误,所以我假设有一些关于有多个路径导致编译器推断null可能是一个自动装箱的int Why can javac not fail to compile both cases with the same error? 为什么javac能够以相同的错误编译这两种情况?

In the first case, the compiler knows that you're trying to unbox a compile-time constant of null . 在第一种情况下,编译器知道您正在尝试将编译时常量取消设置为null

In the second case, the type of the conditional expression is Integer , so you're effectively writing: 在第二种情况下,条件表达式的类型是Integer ,因此您可以有效地编写:

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

... so the unboxing isn't happening on a constant expression, and the compiler will allow it. ...所以取消装箱不会发生在常量表达式上,编译器会允许它。

If you changed it to force the conditional expression to be of type int by unboxing there , it would fail: 如果你改变它以通过在那里取消装箱强制条件表达式为int类型,它将失败:

// Compile-time failure
return new Random().nextBoolean() ? 1 : (int) null;

Boxing partially hides the distinction between primitives and corresponding wrapper objects, but it doesn't remove it. Boxing部分隐藏了基元和相应的包装器对象之间的区别,但它并没有将其删除。

There are two distinctions which are not changed by boxing: 拳击没有改变两个区别:

  • objects can be null, while primitives cannot 对象可以为null,而基元则不能
  • objects have both state and identity, while primitives have only state (the value) 对象具有状态和标识,而基元只有状态(值)

Occasionally, these differences can cause problems when using boxing. 偶尔,这些差异可能会导致使用拳击时出现问题。

Some points to remember : 有些要记住的要点:

  • be careful with nulls. 小心空值。 Auto-unboxing a null object will cause a NullPointerException . 自动取消装箱空对象将导致NullPointerException
  • comparing items with == and equals must be done with care. 比较项目与==equals必须小心。

You can't assign null to an int 您不能将null分配给int

    int anInt = null;

Java allows this since you are not assigning null to an int Java允许这样做,因为您没有为int赋值null

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

If you perform this, you can get the error 如果执行此操作,则可以获得错误

    int anInt = getSomeVal();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM