日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

java 可选参数_超干货详解:kotlin(4) java转kotlin潜规则

發布時間:2025/3/15 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java 可选参数_超干货详解:kotlin(4) java转kotlin潜规则 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

往期推薦

如果面試時大家都說真話...
這400道面試題,決定了你去BAT還是TMD

前言

以一個java老鳥的角度,如何去看 kotlin。 Java源代碼應該如何用Kotlin重構。 如何正確學習kotlin并且應用到實際開發中。本文將會探究。

本文分兩大塊,重難點和潛規則。

重難點:Kotlin中可以獨立出來講解的大塊知識點。提供單獨Demo。這部分大多數是Kotlin開創的新概念(相比于Java)。

潛規則:Kotlin是谷歌用來替換Java的,它和java百分百完全兼容,但是實際上java轉成kotlin之后,需要我們手動修改很多東西,甚至某些部分必須打散重構來達到最優編碼。其中,kotlin的某些特性和java不同,甚至完全反轉。這部分知識點比較零碎,單獨Demo不方便提供,就以小例子的形式來寫。

正文大綱

  • 重難點
    • lambda以及操作符
    • 高階函數以及操作符
    • Kotlin泛型
    • 集合操作
    • 協程
    • 操作符重載
  • 潛規則
    • Kotlin文件和類不存在一對一關系
    • 共生體
    • 繼承
    • 修飾符
    • 空指針問題

正文

潛規則

從Java轉到kotlin,基本上都會存在java代碼與kotlin共存的問題。而且為了快速轉型,可能會直接把java類轉成kotlin類,而這個過程中,涉及到java和kotlin的交互,往往會磕磕碰碰,以下總結了一部分 java kotlin交互方面的問題.

Kotlin文件和類不存在一對一關系

kotlin的文件,可以和類名一致,也可以不一致。這種特性,和c++有點像,畢竟c++的.h 和 .cpp文件是分開的。只要最終編譯的時候對的上,文件名其實無所謂的。Java中,一個類文件的類名和文件名不一致,如果是public類,就會報異常。

在kotlin中,可以寫成一致,如:

不一致:

這樣做的意義在于:

如果有很多個行數很短的類:在java中可能要占用大量的文件個數(Java中可以用內部類的形式解決),kotlin中則可以把這些類都放到同一個kt文件中,不用內部類也能解決。


共生體

Java中的靜態 static關鍵字,在kotlin中不復存在,作為替換,Kotlin提出了共生體的概念。如果是kt文件去調用kt類的“靜態”方法(不依賴對象),則要求后者的類結構中增加一個 companion object 成員變量。并且可以在 成員中寫上 你想要定義的"靜態"成員變量和成員方法

class Test001(_name: String) : Person(_name) {companion object {const val s: String = ""const val s2: String = ""fun t1(){}} }fun main(){Test001.sTest001.t1() }

注:每一個kotlin類中,只能有一個共生體對象.

但是在java調用kt的"靜態"成員方法時,必須帶上共生體,但是,訪問"靜態"成員變量,則不能帶:

public static void main(String[] args) {Test001.Companion.t1();//Java訪問kt的t1()共生體方法,必須帶上CompanionString s2 = Test001.s;// 而訪問共生體成員變量,不能帶Companion}

好糾結。為什么要這么設計。算了。查了一下kt反編譯之后的Java源碼:

共生體變成了Java類中的靜態內部類,包含t1()方法。而s,s2 則是普通的靜態變量。


修飾符

修飾符指的是 類 和 成員變量,成員方法 前面的 權限訪問關鍵字。原 Java擁有 private ,protected,default ,public ,訪問權限分別為: 本類內部,同包名或子類,同包名,全局。

然而,kotlin新增了一個概念,internal ,表示,相同Module內可訪問,跨Module則不行。

并且,java和kotlin的 private ,protected,default ,public 的訪問權限還有區別,但是我這里就不詳述了,因為我覺得意義不大。能不能訪問,寫代碼的時候編譯器會告訴你,當場警告你,你就會修改代碼。如果有問題。可以把kotlin Decompile成Java代碼自己去對比試試。如有需要,后期再說吧。


空指針問題

通常要快速的將 舊java代碼轉化成kotlin代碼,是拷貝java代碼粘貼到kotlin文件內,讓as自動轉化,但是這種方式,容易造成很多空指針問題,有一些是很直白的報了編譯錯誤,而有一些則是隱藏起來,等到程序運行時才會報錯。直接報錯的就不提了,下面演示隱藏的空指針問題:

Kotlin類:

class Student(name:String) {var name: String = namefun showName(tag: String) {println("$tag : $name")} }

Java調用kt:

public class Main {public static void main(String[] args) {Student s = new Student("zhou");s.showName(null);} }

此時,如果運行main函數,就會報出:

告訴我們參數tag不可為null。但是奇怪的是,在java代碼中,居然不會報編譯錯誤。賊特么詭異。

解決方案:

在方法參數后面加上問號,變成這樣:


沒有基本數據類型

Kotlin之中沒有基本數據類型,它只有:Int,Short,Long,Float,Double,Byte ,Char,Boolean 這樣的包裝類型。
為什么沒有?沒有必要去糾結,但是只提供包裝類型有一個好處,那就是 方便擴展函數的定義。
我們可以很輕松地對 Int,類型去擴展函數。
比如: Kotlin自帶了很多擴展函數:

這是系統定的,我們也可以自己來定義:

fun Int.plus100(): Int {//自定義擴展return this + 100 } fun main() {val a: Int = 20println("${a.plus100()}") }

繼承

在用kt重構部分模塊的過程中,我發現頻繁出現下面的問題:

Kotlin基類:

abstract class Person(name: String) {var name: String? = name }

Java子類:

由于我是從基礎類開始重構,所以,在原先的Java代碼中頻繁出現了類似這種 訪問權限不足的問題。一個一個去改成setName函數,工作量巨大。后來找到一個辦法:

在kotin中加入 @JvmField 變成這樣:

abstract class Person(name: String) {@JvmFieldvar name: String? = name }

@JvmField可以讓 kotlin的成員屬性變成公有的,kt轉化成java時,會是如下這樣:

public abstract class Person {@JvmField@Nullablepublic String name;public Person(@NotNull String name) {Intrinsics.checkParameterIsNotNull(name, "name");super();this.name = name;} }

兼容原先的Java代碼。不用大面積修改了。


默認支持可選命名參數

了解高級語言語法的同學肯定知道 可選命名參數和 可選位置參數,經測試: Kotlin的任何方法(包括構造方法和普通和方法),可以這么寫:

fun test001(s: String, s1: String) {println("$s - $s1") }fun main() {test001(s = "1111", s1 = "2222") //臥槽,Kotlin默認支持 可選命名參數 }

這種特性可以很好的避免了Java中出現的一個方法包含N個參數 把人眼睛看花的情況:

private void test(String s1, String s2, String s3, String s5, String s6, String s7, String s8, String s9, String s10, String s11, String s12) {//...}

比如如上面所示,一個方法,有12個String參數,看多了會罵娘,誰特么寫的。然而,用kotlin:

fun test(s1: String, s2: String, s3: String, s4: String, s5: String, s6: String, s7: String, s8: String, s9: String, s10: String, s11: String, s12: String) {} fun main() {test(s1 = "",s2 = "",s3 = "",s4 = "",s5 = "",s6 = "",s7 = "",s8 = "",s9 = "",s10 = "",s11 = "",s12 = "") }

直覺上這種語法,融入了 建造者設計模式。讓同一個函數的多個參數不再混亂。當然如果你懷舊的話,你也可以用原始方法,12個string依次擺下去。反正我不會這么做。


類,成員方法 默認封閉

和Java相反,kotlin給類,成員方法 都采用了默認封閉原則。具體體現為:類,默認不可繼承,成員方法默認不可重寫(繼承時)。如果要繼承類,或者重寫父類方法,必須在父類中手動加入 open 關鍵字,子類中重寫方法必須加上override關鍵字 :

kotlin父類:

open class Student(name:String) {var name: String = nameopen fun showName(tag: String?) {println("$tag : $name")} }

kotlin子類:

class StudentExt(name: String) : Student(name) {override fun showName(tag: String?) {super.showName(tag)println("xxxxx")} }

Kotlin中方法和函數的區別

函數,是c/c++的詞匯,而方法,則是Java里面。現在kotlin中同時存在了方法和函數,那么區別在哪里?

通常我們人為:在Kotlin類內部,稱為成員方法。而在類外部定義的,則成為全局函數(這里就不用去討論kotlin變成java之后長什么樣)。

應用到具體場景,一句話解釋清楚:

A.kt 中有一個A類,它有a()成員方法。 同時我們可以在 B.kt中給A類擴展一個函數。創建一個A類對象之后,我們既可以調用a()成員方法,又可以調用它的擴展函數。

A.kt

class A {fun a() {} }

B.kt

fun A.foo(){}// 擴展A的一個函數fun main() {val a = A()//創建對象a.a() //調用成員方法a.foo() //調用擴展函數 }

結語

Java轉kotlin,給我的感覺就是:

  • kotlin對于一個function內部的管理更加有條理,它引入了 scope 作用域的概念,利用基于lambda表達式的高階函數,把function內部的代碼塊管理起來,讓代碼可讀性更高
  • kotlin的代碼行數會大大減少,因為kotlin設計了很多頂層函數,高階函數,使用大量的鏈式調用,把可以占用行數的代碼都濃縮在一行。這樣做的結果是,一行代碼的信息量大大增加,對于新手是噩夢,但是對于kotlin熟手,會感覺很美妙。
  • 關于協程,本文只做了最簡單的管中窺豹描述,未曾詳細說到的東西還有很多。但是可以肯定一點,協程的出現,顛覆了 android開發的異步編程思維,原本很多不敢想的,原本很多java實現起來要繞很多路的,在kotlin上都可以很優雅地實現。
  • 如果覺得本文不錯別忘了給小on點個贊哦~

    總結

    以上是生活随笔為你收集整理的java 可选参数_超干货详解:kotlin(4) java转kotlin潜规则的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。