当前位置: 首页 > 知识库问答 >
问题:

Java三元算子函数重载[重复]

越宣
2023-03-14

可能重复:
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)

共有2个答案

子车成和
2023-03-14
  1. 类型为integer-自动装箱到10。
  2. 调用
  3. f(int),因为它是唯一可接受的可用的从Integer强制转换(假设没有其他重载)
    当您尝试将null强制转换为int时-您得到了您的NPE。

<罢工> 2. 调用f(Object)是因为Integer是一个对象。这叫做 参考类型加宽
(很抱歉最初的错误,请将其读作f(对象))

颛孙昆
2023-03-14

首先,这个问题与您有f的重载版本无关。如果只有f的版本采用int,则会出现同样的问题。

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

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

第二步是将此integer传递给f。因为f采用int,所以它是自动解箱的。

如果您自动解箱一个integernull,您将得到一个nullPointerException-这就是这里发生的情况。

 类似资料:
  • C++ 允许在同一作用域中的某个函数和运算符指定多个定义,分别称为函数重载和运算符重载。 重载声明是指一个与之前已经在该作用域内声明过的函数或方法具有相同名称的声明,但是它们的参数列表和定义(实现)不相同。 当您调用一个重载函数或重载运算符时,编译器通过把您所使用的参数类型与定义中的参数类型进行比较,决定选用最合适的定义。选择最合适的重载函数或重载运算符的过程,称为重载决策。 C++ 中的函数重载

  • 使用以下代码: 结果: 而切换其他定义的注释块会导致: 坏的版本(有三个参数)是我想要的,有人能解释一下为什么它坏了吗?

  • 问题内容: 覆盖和过载之间有什么区别? 问题答案: 重载:在编译时根据指定参数的数量和类型选择方法 签名 覆盖:在执行时根据目标对象的实际类型(与表达式的编译时类型相对)选择方法 实现 例如: 这两个调用都是 重载的 示例。有两种方法,称为,编译器确定要调用的签名。 第一次调用是 覆盖 的示例。编译器选择签名“ foo(int)”,但是在执行时,目标对象的类型确定要使用的实现应为in中的一个。

  • 有没有可能改变这一点: …一个三元运算符?

  • 有没有可能改变这一点: 到三元运算符?

  • 运算符重载 对于面向对象的程序设计来说,运算符重载可以完成两个对象之间的复杂操作,比如两个对象的加法、减法等。运算符重载的原理是:一个运算符只是一个具有特定意义的符号,只要我们告诉编译程序在什么情况下如何去完成特定的操作,而这种操作的本质是通过特定的函数完成的。 重载运算符 为了重载运算符,首先要定义运算符重载函数,它通常是类的非静态成员函数或者友元函数,运算符的操作数通常也应为对象。 定义运算符