天天看點

Kotlin-42.kotlin調用Java之四(Call Java from Kotlin)

官方文檔: http://kotlinlang.org/docs/reference/java-interop.html

繼續上一章

10.Object類方法(Object Methods)

在Kotlin中導入(import)Java類型時,java.lang.Object類都(映射)轉成kotlin.Any!
但時Any不是平台指定,kotlin.Any成員隻有toString(),hashCode(),equals(),
是以為了使用java.lang.Object的其它成員,Kotlin.Any需要添加擴充函數,如下所示:  

1.wait()/notify()
在《Effective Java》第69條建議優先使用并發工具(concurrency utilities),不建議使用wait()和notify()!
是以在kotlin中Any類型不提供wait()和notify()方法!
如果需要在Kotlin調用它們,可将kotlin類轉換為java.lang.Object,例如:
    //foo是kotlin類,所有kotlin類都繼承Any類
    (foo as java.lang.Object).wait()

2.getClass()
在Kotlin中擷取對象的Java class類,可在類引用(對象)上使用java擴充屬性:
    //foo是kotlin對象,fooClass是java class
    //1.使用自Kotlin 1.1起支援的綁定類引用(bound class reference)
    val fooClass = foo::class.java

    //2.也可以使用javaClass擴充屬性:
    val fooClass = foo.javaClass

3.clone()
在kotlin中重寫/覆寫clone()方法,需要繼承kotlin.Cloneable,例如:
    class Example : Cloneable {
        override fun clone(): Any {
        }
    }
别忘了《Effective Java》第11條: 謹慎(Override)覆寫clone()方法!

4.finalize()
在kotLin中覆寫finalize(),隻需簡單地聲明它,而不需要override關鍵字(無需繼承/實作):
    class C {
        //根據Java規則,finalize()不能為private 
        protected fun finalize() {                
            // 結束邏輯                           
        }
    }
           

11.Java類(Java class)

1.通路java類的靜态成員(static members)
在kotlin中Java類的靜态成員會形成該類的伴生對象(companion object),無法将伴生對象作為值來傳遞,
但可以顯式通路其成員,例如:
    //Character是java類,isLetter()是靜态成員,但在kotlin是伴生對象的成員
    if (Character.isLetter(a)) {       
    }

2.Java反射(Java Reflection)
在Kotlin中可以使用Java反射,可以通過instance::class.java, instance.javaClass, 
ClassName::class.java (其中instance是執行個體對象,ClassName是類)    
擷取java.lang.Class類,進而使用Java反射相關的方法類庫!

其它情況支援包括:
    為Kotlin屬性擷取Java字段的getter/setter方法或者幕後字段,
    為Java字段擷取Kotlin屬性(KProperty)
    為Kotlin函數(KFunction)擷取Java方法或者構造函數,反之亦然!
           

12.SAM轉換(SAM Conversions)

像Java 8一樣,Kotlin支援SAM轉換(Single Abstract Method),
意味着Kotlin函數字面值可被自動轉換成隻有一個非預設方法的Java接口實作!
SAM轉換隻适用于接口,而不适用于抽象類,即使抽象類隻有一個抽象方法!
SAM轉換隻适用于kotlin與Java互操作,因為Kotlin不需要将函數自動轉換為Kotlin接口實作!

總結: 說白了就是為了在kotlin對Java方法使用lambda表達式,SAM轉換例子:
    val runnable = Runnable {
        println("This runs in a runnable")
    }

    val executor = ThreadPoolExecutor()

    //Java類execute方法隻有一個參數(接口)
    executor.execute {
         println("This runs in a thread pool")
    }

    //Java類execute方法有多個參數(接口)
    executor.execute(Runnable { println("This runs in a thread pool") })
           

13.在Kotlin中使用JNI

聲明一個在本地(C或C++)代碼中實作的函數,需要使用external修飾符标記:
    external fun foo(x: Int): Double
其餘過程與Java的JNI工作方式完全相同
           

CSDN部落格: http://blog.csdn.net/qq_32115439/article/details/75208980

GitHub部落格:http://lioil.win/2017/07/16/Kotlin-javaInKotlin4.html

Coding部落格:http://c.lioil.win/2017/07/16/Kotlin-javaInKotlin4.html