• Java调用Kotlin程序深度解析


    异常:

    在之前我们已经学习在Kotlin中的所有异常都是运行期的,而不像Java分为运行期和非运行期,下面用代码来演示一下,先建一个Java的异常:

     

    然后在Kotlin中来调用一下该Java中的方法

    很明显IOException在Java是需要检查的异常,然后在Kotlin中居然是不需要进行异常处理,而在运行时肯定就抛出异常了:

    在Kotlin中获取Java类型:

    另外在Kotlin中如何来获取它具体Java对应的类型呢,可以如下:

    还有另外一种方式也可以获取:

    其中可以看一下它的定义:

    Java调用Kotlin:

    对于Kotlin怎么来调用Java已经学习了,而接下来反着来用一下,这要稍复杂一下,下面开始:

    属性(properties):

    一个Kotlin属性会被编译为3部分元素:

    1、一个getter方法。

    2、一个setter方法。

    3、一个私有的字段(field),其名字与Kotlin的属性名一样。

    下面来定义一个论证一下上面的理论:

    如何来论证呢?当然得反编译啦:

     

    此时需要再加一个参数才能看到,如下:

    但是需要注意一点:如果Kotlin属性名以is开头,那么命名的约定会发生一些变化,具体如下:

    1、getter方法名与属性名一样。

    2、setter方法名则将is替换为set。

    3、一个私有的字段(field),其名字与Kotlin的属性名一样。

    这种规则适用于任何类型,而不单单是Boolean类型。

    下面再来验证一下此理论:

    方法:

    我们知道在Kotlin中的方法可以不属于任何类,如下:

    但是很明显它不符合Java的规则,而最终都会编译成jvm字节码肯定得遵照Java的规则,所以下面来研究一下它的机理,先看代码: 

    咱们再来新建一个Java文件,来调用Kotlin:

    首先来调用我们在Kotlin定义的MyClass,其实直接可以使用,如下:

    那么。。接下来再调用我们在Kotlin定义的test()和str问题就来了,它是依附于哪个类中的呢?我们先来看一下我们的HelloKotlin2.kt编译成了啥?

    其实就是用它来可以直接调用,其中test()和str变成了该类的静态方法和属性,所以可以直接通过类名来调用它们俩,如下:

    好,下面再来一探这个Kotlin在字节码的表现,进一步来加深在Java调用Kotlin的用法:

    xiongweideMacBook-Pro:kotlin_lecture xiongwei$ javap -c -p com/kotlin/test11/HelloKotlin2Kt.class
    Compiled from "HelloKotlin2.kt"
    public final class com.kotlin.test11.HelloKotlin2Kt {
      private static java.lang.String str;
    
      public static final void test();
        Code:
           0: ldc           #8                  // String hello world
           2: astore_0
           3: iconst_0
           4: istore_1
           5: getstatic     #14                 // Field java/lang/System.out:Ljava/io/PrintStream;
           8: aload_0
           9: invokevirtual #20                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
          12: return
    
      public static final java.lang.String getStr();
        Code:
           0: getstatic     #27                 // Field str:Ljava/lang/String;
           3: areturn
    
      public static final void setStr(java.lang.String);
        Code:
           0: aload_0
           1: ldc           #31                 // String <set-?>
           3: invokestatic  #37                 // Method kotlin/jvm/internal/Intrinsics.checkParameterIsNotNull:(Ljava/lang/Object;Ljava/lang/String;)V
           6: aload_0
           7: putstatic     #27                 // Field str:Ljava/lang/String;
          10: return
    
      static {};
        Code:
           0: ldc           #54                 // String hello
           2: putstatic     #27                 // Field str:Ljava/lang/String;
           5: return
    }

    那既然生成的类是HelloKotlin2Kt,那是不是我们可以直接来生成它的实例呢?下面试试:

    貌似木有问题,那运行一下呗:

    为啥呢?那我们看一下字节码中看一下,确实是木有生成构造方法。。好奇怪,对于普通的Java类编译生成的字节码肯定会生成一个构造方法,所以总结如下:“我们是无法通过new关键字来创建Kotlin编译器自动生成的以Kt结尾的类的实例的,因为Kotlin编译器在生成的字节码中没有不带参数的构造方法。”

    这是跟Java存在很大差别的,也违背了我们一贯的认知,所以需要非常注意!!!

  • 相关阅读:
    ABB机器人 带参数例行程序
    面试题10- I:斐波那契数列(C++)
    面试题39:数组中出现次数超过一半的数字(C++)
    面试题50:第一个只出现一次的字符(C++)
    第八部分 表的基本操作
    第七部分 表中数据的基本操作
    面试题18:删除链表的节点(C++)
    面试题35:复杂链表的复制(C++)
    面试题54:二叉搜索树的第k大节点(C++)
    面试题62:圆圈中最后剩下的数字(C++)
  • 原文地址:https://www.cnblogs.com/webor2006/p/11537866.html
Copyright © 2020-2023  润新知