在Java中使用if与三元运算符时的“Wrong”返回类型

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (11)

在下面的类中,两种方法的返回类型与三元运算符的思想不一致:

return condition?a:b;

相当于

if(condition) {
    return a;
} else{ 
    return b;
}

第一个返回一个Double和第二个Long:

public class IfTest {
    public static Long longValue = 1l;
    public static Double doubleValue = null;

    public static void main(String[] args) {
        System.out.println(getWithIf().getClass());// outpus Long
        System.out.println(getWithQuestionMark().getClass());// outputs Double
    }

    public static Object getWithQuestionMark() {
        return doubleValue == null ? longValue : doubleValue;
    }

    public static Object getWithIf() {
        if (doubleValue == null) {
            return longValue;
         } else {
            return doubleValue;
        }
    }
}

我可以想象这与编译器缩小返回类型有关,getWithQuestionMark()但是语言明智吗?这当然不是我所期望的。

提问于
用户回答回答于

基本上它遵循JLS第15.25节的规则,具体来说:

否则,如果第二个和第三个操作数的类型可以转换(§5.1.8)为数字类型,则会出现以下几种情况:

  • [...]
  • 否则,对操作数类型应用二进制数字提升(第5.6.2节),并且条件表达式的类型是第二个和第三个操作数的提升类型。

因此,第5.6.2节将遵循,这将基本上涉及拆箱 - 所以这使得您的表达式分别起作用,longValue并且doubleValue分别是类型longdouble扩展,并将扩展升级应用于long获取整体结果类型double

double是那么为了返回一个盒装Object的方法。

用户回答回答于

看看你看到的字节码:

public static java.lang.Object getWithQuestionMark();
  Code:
   0:   getstatic       #7; //Field doubleValue:Ljava/lang/Double;
   3:   ifnonnull       16
   6:   getstatic       #8; //Field longValue:Ljava/lang/Long;
   9:   invokevirtual   #9; //Method java/lang/Long.longValue:()J
   12:  l2d
   13:  goto    22
   16:  getstatic       #7; //Field doubleValue:Ljava/lang/Double;
   19:  invokevirtual   #10; //Method java/lang/Double.doubleValue:()D
   22:  invokestatic    #11; //Method java/lang/Double.valueOf:(D)Ljava/lang/Double;
   25:  astore_0
   26:  aload_0
   27:  areturn

而如果你告诉编译器你对数字不感兴趣:

public static Object getWithQuestionMark() {
    return doubleValue == null ? (Object)longValue : (Object)doubleValue;
}

你会得到你以后的(字节码)

public static java.lang.Object getWithQuestionMark();
  Code:
   0:   getstatic       #7; //Field doubleValue:Ljava/lang/Double;
   3:   ifnonnull       12
   6:   getstatic       #8; //Field longValue:Ljava/lang/Long;
   9:   goto    15
   12:  getstatic       #7; //Field doubleValue:Ljava/lang/Double;
   15:  areturn

输出:

$ java IfTest
class java.lang.Long
class java.lang.Long

扫码关注云+社区