有关java和kotlin的三目运算符


#1

java代码

public class Main {
    public static void main(String[] args) {
        int a = 1, b = 2;
        testFunc(a, b);
    }

    private static void testFunc(int a, int b) {
        System.out.println(a == b ? 'a' : 98);
    }
}

发现代码跑出来的结果是

b

convert java file to kotlin file

object Main {
    @JvmStatic
    fun main(args: Array<String>) {
        val a = 1
        val b = 2
        testFunc(a, b)
    }

    private fun testFunc(a: Int, b: Int) {
        println(if (a == b) 'a' else 98)
    }
}

跑出来结果是

98

有大佬能说明一下吗?
原文链接点这里


#2

你把98改成97他就输出a


#3

好像在java中三目运算符的返回值类型跟第一个冒号后面的类型有关的,但是在kotlin里面移除了三目运算符,使用if else结构就不会受前面的类型影响了,我看了kotlin字节码反编译成java代码,发现它用Object来接受的三目运算符的返回值

   private final void testFunc(int a, int b) {
      Object var3 = a == b ? 'a' : 98;
      boolean var4 = false;
      System.out.println(var3);
   }

#4

但是实际上在java中

a == b ? 'a' : 98

被当做是char类型
所以调用的是下面这个方法

    public void println(char x) {
        synchronized (this) {
            print(x);
            newLine();
        }
    }

#5

Java 当中有类型隐式转换,Kotlin 当中没有。从结果来看, Java 当中整型字面量会被隐式转为 char,也就是三目运算表达式的类型;而 Kotlin 当中,if else 表达式返回值类型的推导是根据分支的公共父类来推算的 ,Char 和 Int 的公共父类是 Any,不存在类型转换,因此 else 分支返回值的类型 98 始终是 Int 类型,而 println 的重载选择则是按照编译期绑定到了Any上面,所以输出 98。


#6

image


#7

刚想这样写试下java里的类型推断,看看c是啥类型

    private static void testFunc(int a, int b) {
        val c = a == b ? 'a' : 98;
        System.out.println(a == b ? 'a' : 98);
    }

但是为啥我的java11不支持val 啊:joy:
image


#8

image


#9

我发的代码是用Android Studio写的kotlin代码,编辑器会自动推断出表达式的类型是Any类型,并提示’a’和98都被隐式转换成了Any类型,java不支持val,想看表达式返回类型可以用下面代码打印

private void testFunc(int a, int b) {
        Object c = a == b ? 'a' : 98;
        System.out.println(c.getClass().getName());
    }

得出值为"java.lang.Character"类型


#10

kotlin确实是你说的结果,霍老师在前面的回答也提到了这点,我现在想知道的是我的jdk11为啥不支持类型推断了:sweat:我记得当时我用jdk10的时候还体验了一下用val定义常量,怎么现在就不行了呢:stuck_out_tongue:


#11

很抱歉我只用过java 8,不过据我的搜索结果来看java 10只添加了var作为保留类型,并没有val,可以用final var 来替代,参考
https://blog.csdn.net/rickiyeat/article/details/79101931


#12

java也就是个var而已,从10开始的


#13

确实是只有var,是我记错了


#14

其实昨天我var也不能用,今天才发现是我的项目是用gradle创建的(我之前是1.8),所以要设置

sourceCompatibility = 1.11

发这个讨论帖的目的主要是想搞清楚java中三目运算符表达式的返回值与什么有关,现在已经了解了,非常感谢benny老师,继续膜拜,向大佬学习!


#15

java里面是 var ,并没有 val :rofl:


#16

是的 已经知道了:joy:
话说为啥你的表情可以发出来 我的表情就是字符串啊:sweat::sweat::sweat:


#17

你在java代码用val定义变量,这肯定报错啊


#18

主要想用val 来看看表达式的类型,忘了java中只支持var,下面是这个问题的一个小总结

public class Main {
    public static void main(String[] args) {
        testFunc(1, 2);
    }

    private static void testFunc(int a, int b) {
        var m0 = a == b ? 'a' : 98;
        var m1 = a == b ? 'a' : 98L;
        var m2 = a == b ? 'a' : 98.0;
        var m3 = a == b ? 'a' : (short) 98;
        System.out.println(m0);
        System.out.println(m1);
        System.out.println(m2);
        System.out.println(m3);
    }
}

输出结果是

b
98
98.0
98

下面是编译器类型推断的截图
image


京ICP备16022265号-2 Kotlin China 2017 - 2018