欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

秒懂Kotlin之Java工程師快速掌握Kotlin的技巧

 更新時間:2021年09月02日 11:39:18   作者:ShuSheng007  
Kotlin 是一種在 Java 虛擬機上運行的靜態(tài)類型編程語言,被稱之為 Android 世界的Swift,由 JetBrains 設(shè)計開發(fā)并開源。這篇文章主要介紹了秒懂Kotlin之Java工程師快速掌握Kotlin的技巧,需要的朋友可以參考下

概述

Kotlin 是一種在 Java 虛擬機上運行的靜態(tài)類型編程語言,被稱之為 Android 世界的Swift,由 JetBrains 設(shè)計開發(fā)并開源。

Kotlin 可以編譯成Java字節(jié)碼,也可以編譯成 JavaScript,方便在沒有 JVM 的設(shè)備上運行。

在Google I/O 2017中,Google 宣布 Kotlin 成為 Android 官方開發(fā)語言。

Kotlin/JVM 可以看做是對改進Java的一種積極的嘗試,其試圖改進Java編程語言中已知的被廣泛討論的缺點與不足。因為我多年前從事過C#的開發(fā),初次看到Kotlin,感覺好多特性C#好多年前就有了。足見Java是多么的傳統(tǒng),不愿意過多的引入語法糖。

關(guān)于Kotlin與Java的愛恨情仇此處按下不表,等有機會單獨寫一篇相關(guān)文章。本文僅想從Java慣用者的角度給出Kotlin與Java的一些不同點,這往往對Java慣用者迅速掌握Kotlin是至關(guān)重要的。因為Kotlin是對Java的一種改進,其與Java是100%互操作的,所以Java程序員經(jīng)過短暫的熟悉后往往可以快速入門,進而熟練掌握Kotlin。

人類學(xué)習(xí)新事物的一個很重要的方法就是類比,如果新事物與舊事物相似性非常大,那么類比學(xué)習(xí)的效果會更加明顯,從Java到Kotlin非常符合這個特征,以你熟悉的Java來類比不熟悉的Kotlin將會事半功倍,讓我們開始吧。

本文基于Kotlin 1.4.0 版本

語法差異

Kotlin與Java在語法上存在一些差異,不算特別巨大,下面列出了我認為最需要適應(yīng)的幾條:

Kotlin中的方法和屬性可以不包含在

我們知道,Java中的一切是以class為基礎(chǔ)的,都要在class中,但是Kotlin卻不是。下面的代碼中,方法、屬性以及類共存于同一級,同一個文件中都是允許的。

//屬性
var name: String = "ShuSheng007"

//方法
fun sum(x: Int, y: Int): Int {
    return x + y
}

//類
class Student{}

Kotlin中語句不需要以;結(jié)束

println("hello world")

Kotlin中數(shù)據(jù)類型是后置的

//變量聲明時類型后置
var name: String = "ShuSheng007"

//方法參數(shù)及返回值類型后置
fun sum(x: Int, y: Int): Int {
        return x + y
}

Kotlin方法使用fun關(guān)鍵字定義

fun sum(x: Int, y: Int): Int {
        return x + y
}

Kotlin的類和方法默認是public final的

類默認不可以被繼承,基類中的方法默認不可以被重寫,如果想要被繼承或者重寫需要用open關(guān)鍵字標記

//Human類可以被繼承
open class Human{
	//eat方法可以被overwrite
    open fun eat(){
    }
}

Kotlin中類繼承和接口實現(xiàn)使用:標記

//類繼承
class Man : Human(){
    override fun eat() {
        super.eat()
    }
}

//實現(xiàn)接口
interface action{
    fun sleep()
}
class Woman :action{
    override fun sleep() {
        //...
    }
}

Kotlin中使用var,val聲明變量及屬性,而且可以進行類型推斷

在Java中,我們聲明一個變量必須先指定其類型,例如

String name= "shusheng007";

但是在Kotlin中,編譯器可以根據(jù)賦值自動推斷其類型為String

var name = "shusheng007"

Kotlin存在非空與可空類型

這個也是其宣傳的一大亮點,嘗試去解決價值幾十億美金的問題:NullPointerException

在Kotlin中每個對象默認都是非null的,除非你顯式的將其聲明為可null

//非空類型
var name1:String="shusheng"
//可空類型
var name2:String?=null

Kotlin中package可以與文件路徑不一致

什么意思呢?假設(shè)我們有個類文件在 src/…/top/ss007/learn 文件路徑中

那么對于Java 此類的包名必須為

package top.ss007.learn

而對于Kotlin來說就沒有這個限制,可以隨便叫,例如叫:就是這么任性

package just.so.wayward

確實挺任性的,所以這點建議還是遵守Java的規(guī)范更好。

Kotlin中沒有受檢異常(Checked Exception)

在Java中有很多受檢查異常,程序員被強制要求處理它,或者拋給下層調(diào)用者處理。但是Kotlin沒有這個限制。

Kotlin強調(diào)不可變的概念

Kotlin會優(yōu)先使用不可變對象,例如不可變的集合,不可變的變量。這些不可變對象生成后就只能讀取,而不能修改。至于使用不可變對象有很多好處,例如其天然的線程安全性等

以上幾條是個人認為的最顛覆我們認知的差異點,熟悉了上面幾條后Java程序員就基本上可以看得懂kotlin的代碼了

Java中不存在的特性

Kotlin中引入了很多Java中不存在的特性,下面是幾條我認為比較重要的

方法類型(Function Type)

在Kotlin中方法是一等公民,意思就是方法就和類一樣,類可以干的事,方法都可以干。方法竟然可以作為類型當其他方法的參數(shù)傳遞,當其他方法的返回值類型,當變量的聲明類型…這個比較顛覆Java程序員的三觀,Java中是沒有對應(yīng)的概念的。如果非要找一個對應(yīng)物的話,那就是函數(shù)接口了。

下面是一個方法類型(兩個int 數(shù)據(jù) 得到一個int,例如1+2=3)。我們完全可以將其看成是java中的一個類,所有可以使用類的地方這家伙都適用,也就是說kotlin中,方法可以當參數(shù)傳遞了,相當于實現(xiàn)了方法引用,牛逼哄哄的。

(Int, Int) -> Int

例如如下方法,第3個參數(shù)operation的類型就是上面的方法類型

fun calculate(x: Int, y: Int, operation: (Int, Int) -> Int): Int {  
    return operation(x, y)                                          
}
//如何調(diào)用
fun sum(x: Int, y: Int): Int {
    return x + y
}
//將sum方法當參數(shù)傳入了calculate方法中
calculate(4, 5, ::sum)

//我們也可以使用Lambda表達式
calculate(4, 5, { a, b -> a + b })
//當Lambda表達式是方法的最后一個參數(shù)時,其可以移到()外面
calculate(4, 5) { a, b -> a + b }

那么如何在Java中實現(xiàn)相同的功能呢?

第一步:按照需求定義一個函數(shù)接口

下面的接口只有一個抽象方法,是一個函數(shù)接口。

@FunctionalInterface
public interface Fun2<P1, P2, R> {
    R invoke(P1 p1, P2 p2);
}

第二步:將其作為方法參數(shù)類型

public int javaCalculate(int x, int y, Fun2<Integer, Integer, Integer> operation) {
     return operation.invoke(x, y);
 }

經(jīng)過上面兩步就搞定了。

當在Kotlin中調(diào)用Java中的方法javaCalculate時,IDE會提示如下信息

在這里插入圖片描述

第一條是告訴你第三個參數(shù)可以使用Kotlin中的函數(shù)類型,代碼如下

javaCalculate(4, 5) { a, b -> a + b }

第二條是比較正統(tǒng)的,告知你需要一個類型為Fun2的參數(shù),代碼如下

javaCalculate(4, 5, object : Fun2<Int, Int, Int> {
        override fun invoke(p1: Int, p2: Int): Int {
            return p1 + p2
        }
    })

在Java中我們使用new一個匿名類的對象,而在Kotlin中我們需要使用object關(guān)鍵字

屬性(Property)

var name:String="ShuSheng007"

對應(yīng)Java類里的私有字段(Field)外加getter和setter方法

private String name;

public String getName() {
    return name;
}
public void setName(String name) {
    this.name = name;
}

數(shù)據(jù)類 data class

data class User(val name: String, val age: Int)

大體相當于Java中的JavaBean,但有細微差別,這也是Kotlin大勢宣傳其簡潔性時經(jīng)常展示的看家特性

密封類 ( Sealed Classes)

這個比較牛逼,Java中沒有對應(yīng)的東東,其主要配合Kotlin中的when使用。最開始見到它的時候我不是很喜歡它,因為它名叫密封類,卻可以被繼承,后來發(fā)現(xiàn)了它設(shè)計的精妙性,真的實質(zhì)性的解決了開發(fā)中常常遇到的困境。

  • 其是一種繼承受限的類,例如下面的Human類,其具有如下特點
  • 其是abstract類其不可以被直接實例化
  • 其子類必須和其處于同一個文件
sealed class Human {
    abstract fun eat(): Unit
    open fun program(){
        println("I use koltin")
    }
}
class Man : Human() {
    override fun eat() {
    }

    override fun equals(other: Any?): Boolean {
        return this === other
    }

    override fun hashCode(): Int {
        return System.identityHashCode(this)
    }
}

class Woman :Human(){
    override fun eat() {
    }

    override fun program() {
        super.program()
    }
}

那它有什么好處呢?主要就是用在when表達式中,和枚舉的功能差不多,但是其可以保護狀態(tài),枚舉是單例的。

擴展方法(Extension functions)與擴展屬性(Extension properties)

這個特性也是kotlin非常重要的特性,有著很廣泛的應(yīng)用。通過擴展方法Kotlin有能力不通過繼承而為某個類增加新的方法和屬性

例如我們想實現(xiàn)一個wrapWithSymbol, 用于在字符串的前后加上<>,如何實現(xiàn)呢?如果是java的話就只能寫一個Utils方法了,而Kotlin可以使用擴展方法來給String類增加一個新方法。

其實現(xiàn)方法如下,注意方法前面的那個要擴展的類型,學(xué)名叫receiver

fun String.wrapWithSymbol() :String{
	return "<$this>"
}

//使用
println("my name is ${"shusheng007".wrapWithSymbol()}")

輸出:

my name is <shusheng007>

可見已經(jīng)在目標字符串前后加上了<>,從調(diào)用方式來看,wrapWithSymbol方法就像是String類的方法一樣。

擴展屬性與擴展方法類似:

val <T> List<T>.lastIndex: Int
    get() = size - 1
    
//調(diào)用
println(listOf(1,2,3,4).lastIndex)

操作符重載

這個其實還是比較復(fù)雜的,也容易被濫用,我認為應(yīng)該屬于進階知識,此處僅簡單的簡紹一下。

Java是不支持操作符重載的,其實有沒有它也不影響大局。

那什么是操作符重載呢?想要理解這個問題,首先必須理解什么是操作符?

例如我們編程時候經(jīng)常用到 a++, a--, a+b, a==b ,a in b等等,其中那些++,--,+,== ,in就是操作符。

那什么是重載呢?這些操作符本身都是有自己的含義的,但是我們通過重載方式可以改變這些操作符的含義,這個過程就叫操作符重載。

在kotlin中,可以重載的操作符集合及其對應(yīng)的方法都是預(yù)先定義好的,不能隨便重載。下面列出其中的一組:

Expression Translated to
a + b a.plus(b)
a - b a.minus(b)
a * b a.times(b)
a / b a.div(b)
a % b a.rem(b), a.mod(b) (deprecated)
a…b a.rangeTo(b)

操作符重載的方法既可以是實例方法,也可以是擴展方法。

我們嘗試使用實例方法重載一下上表中的+操作符。有兩點需要注意:

  1. 重載方法必須以operator 標記
  2. 重載方法名稱和參數(shù)必須是Kotlin預(yù)先定義好的,例如此處的 plus
data class Point(val x: Int, val y: Int){
	operator fun plus(p: Point): Point {
        return Point(p.x + x,p.y + y)
    }
}

//調(diào)用
 val p1 = Point(1, 2)
 val p2 = Point(3, 4)
 println(p1 + p2)

輸出:

Point(x=4, y=6)

可見,通過重載+操作符,我們改變了其內(nèi)在的含義,使得+也能用于對象了。

協(xié)程

較復(fù)雜,需要單獨文章描述

到此這篇關(guān)于秒懂Kotlin之Java工程師快速掌握Kotlin的技巧的文章就介紹到這了,更多相關(guān)Kotlin開始入門內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論