Java三元运算符函数重载

时间:2012-10-25 12:59:18

标签: java ternary-operator overloading

  

可能重复:
  Java conditional operator ?: result type
  NullPointerException through auto-boxing-behavior of Java ternary operator

说我有两个功能:

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

我称之为:

f(someCondition ? 10 : null);

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

  1. 为什么甚至编译? foo ? 10 : null的类型是什么?
  2. 它显然不会调用“正确”的功能,因为这不会导致NPE。它调用了哪个功能?它是f((MyObject)10);还是f((int)null)

2 个答案:

答案 0 :(得分:2)

  1. 类型为Integer - 自动装箱已完成10。
  2. 调用
  3. f(int),因为它是Integer中唯一可接受的强制转换(假设没有其他重载)
    当您尝试将null投射到int时 - 您将获得NPE。
  4. 2.调用f(Object),因为Integer是一个Object。这称为引用类型扩展
    (抱歉最初的错误,请将其读作f(Object)

答案 1 :(得分:2)

首先,问题与您重载f版本的事实没有任何关系。如果您的f版本只有int,那么您会遇到同样的问题。

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

因此,Java编译器将查看它是否可以将expr1expr2转换为单一类型。请注意,int不能是null(因为它是基本类型)。但是,10可以通过自动装箱转换为IntegerInteger也可以null。因此,整个三元表达式的类型被确定为Integer类型。结果是包含值Integer的{​​{1}}或包含10的{​​{1}}。

第二步是将Integer传递给null。由于Integer需要f,因此会自动取消装箱。

如果您自动取消f int Integer,则会收到null - 这就是这里发生的事情。