1

可能重复:
Java 条件运算符?:
通过 Java 三元运算符的自动装箱行为的结果类型 NullPointerException

假设我有两个功能:

f(MyObject o) { ... }
f(int i) { ... }

我这样称呼他们:

f(someCondition ? 10 : null);

这可以编译,但是当我运行它时,我得到一个空指针异常(抱歉,我不确定在哪种情况下)。我的一些问题是:

  1. 为什么它甚至可以编译?是什么类型的foo ? 10 : null
  2. 它显然没有调用“正确”函数,因为这不会导致 NPE。那么它调用的是哪个函数呢?是吗f((MyObject)10);f((int)null)
4

2 回答 2

2

首先,问题与您重载了f. 如果你只有那个版本fint你会遇到同样的问题。

问题是三元表达式的两个可能结果(在 之前和之后:)必须具有相同的类型,因为整个表达式condition ? expr1 : expr2必须具有单一类型。您不能让此表达式计算为一种类型conditionis true,如果它是另一种类型false

因此,Java 编译器将查看它是否可以转换expr1expr2单一类型。请注意,int不能null(因为它是原始类型)。但是,10可以Integer通过自动装箱转换为,Integer也可以是null. 所以整个三元表达式的类型被确定为 type Integer。结果要么是Integer包含值10的 要么Integernull

第二步是将其传递Integerf. 因为f需要一个int,所以它是自动拆箱的。

如果你自动拆箱 an Integerthat is null,你会得到一个NullPointerException- 这就是这里发生的事情。

于 2012-10-25T13:13:25.833 回答
2
  1. 类型是Integer- 对 10 进行自动装箱
  2. f(int)被调用,因为它是唯一可接受的来自 Integer 的可用转换(假设没有其他重载)
    当您尝试将 anull转换为 an时int- 您会得到 NPE。

2.f(Object)被调用是因为 Integer 是一个 Object。这称为引用类型扩展
(抱歉最初的错误,请阅读为f(Object)

于 2012-10-25T13:01:46.467 回答