具有不同类型表达式的三元运算符

Lem*_*nov 8 java ternary-operator

我正在玩三元运算符并注意到一些奇怪的东西.我的代码如下:

class Main {

  static void foo(int a){
    System.out.println("int");
  }

  static void foo(String a){
    System.out.println("String");
  }

  static void foo(Object a){
    System.out.println("object");
  }

  public static void main(String[] args) {
    foo(2==3 ? 0xF00:"bar");
    System.out.println((2==3 ? 0xF00:"bar").getClass().getName());
  }
}
Run Code Online (Sandbox Code Playgroud)

结果如何

宾语

java.lang.String中

第一行结果显示该指令使用object参数传递给foo方法.

指令本身导致String的第二行.

题:

  1. 为什么结果是String编译器决定使用Object?

  2. 这是因为类型模糊吗?

  3. 如果是,那么为什么获取类名返回java.lang.String

Leo*_*Aso 8

在Java中,您有编译时类型信息,并且您有运行时类型信息.编译时间类型信息是编译器可以通过查看它而不执行它来推断值或表达式的类型.当编译器看到表达式时

2 == 3 ? 0xF00 : "bar"
Run Code Online (Sandbox Code Playgroud)

它不知道2 == 3是真还是假,因为它不执行代码.所有它知道的结果可能是a Integer或a String.因此,当需要选择foo要调用的方法时,它会选择接受的方法Object,因为这是它知道在两种方案中唯一可用的方法.

但是,当代码实际运行时,2 == 3将为false,结果将为a String,其getClass()方法将返回String.class.这是您需要注意的:getClass()不返回变量在编译时具有的类型,但它返回变量在运行时保存的对象的实际类型.即

Object o = "Hello!";
System.out.println(o.getClass());
Run Code Online (Sandbox Code Playgroud)

将打印java.lang.String,因为即使编译器它是一个Object,在运行时它实际上是一个String.