首页 > 解决方案 > 具有不同类型表达式的三元运算符

问题描述

我在玩三元运算符并注意到一些奇怪的东西。我有以下代码:

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

这导致

目的

java.lang.String

结果的第一行表明该指令使用对象参数传递给foo方法。

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

问题:

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

  2. 这是因为类型不明确吗?

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

标签: javaternary-operator

解决方案


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

2 == 3 ? 0xF00 : "bar"

它不知道2 == 3是真还是假,因为它不执行代码。所以它所知道的只是结果可以是一个Integer,或者一个String。因此,当需要选择foo调用哪个方法时,它会选择接受的方法Object,因为它知道这是唯一一个在这两种情况下都可以工作的方法。

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

Object o = "Hello!";
System.out.println(o.getClass());

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


推荐阅读