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存在很大差別的,也違背了我們一貫的認知,所以需要非常注意!!!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM