Java在程式語言中佔據主導地位,因此我多次看到Java開發人員在使用Kotlin時犯同樣的錯誤。別誤會,這不是說這些是bug,而是當開發人員習慣於在Java中進行開發時,在Kotlin中傾向於產生“代碼異味”,沒有利用Kotlin的功能。
本文將使您了解我經常看到的程式碼異味以及如何在「Kotlin方式」中理想地實現它們。
本系列的第1部分將涵蓋:
這個主題可能很快就會消失,因為我越來越多的Java開發人員也有使用記錄類別的經驗。儘管如此,Java記錄和Kotlin資料類別之間還是有一些區別。
Java方式:
<code class="language-java">public class Person { private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } // Getters, setters, ... }</code>
或作為記錄:
<code class="language-java">public record Person( String name, int age ) { }</code>
Kotlin方式:
<code class="language-kotlin">data class Person(val name: String, var age: Int)</code>
您可能需要了解Java記錄和Kotlin資料類別之間的一些差異。
一些例子:
在Java中複製物件
<code class="language-java">Person p2 = new Person(p1.getName(), p1.getAge());</code>
Kotlin:
<code class="language-kotlin">val p2 = p1.copy(age = 42)</code>
或在Java中解構聲明:
<code class="language-java">String name = p1.getName(); int age = p1.getAge();</code>
Kotlin:
<code class="language-kotlin">val (name, age) = p1 println(name) // "John" println(age) // 42</code>
在我看來,Kotlin中的空安全是最強大的功能之一。這是一個改變遊戲規則的功能,可以節省您大量的時間和麻煩。在Kotlin中,空安全內建於類型系統中,這使得更容易避免與空相關的運行時錯誤。
在Kotlin中,可空類型是明確聲明的。這意味著您可以擁有一個可能保存空值的變量,但您必須在聲明中明確指定它。
不可空型別(預設行為)
預設情況下,Kotlin中的所有類型都是不可空的,這表示變數不能保存空值。
<code class="language-kotlin">val name: String = "John" // 不可空 name = null // 编译错误!</code>
可空型
要聲明一個可以保存空值的變量,您必須使用?運算符。
<code class="language-kotlin">val name: String? = null // 可空</code>
一個強大的功能是安全呼叫運算子?.。它允許您安全地呼叫方法或存取屬性,而不會拋出NullPointerException。
示例
<code class="language-java">public class Person { private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } // Getters, setters, ... }</code>
?.運算符檢查對像是否為空,如果為空,則立即返回null,否則繼續調用方法或訪問屬性。如果對象為空,則整個表達式計算結果為null。
Elvis運算符?:是如果運算符左側的表達式為空則返回默認值的簡寫。
<code class="language-java">public record Person( String name, int age ) { }</code>
您可以使用!!運算符告訴編譯器該值不為空。如果該值為null,它將拋出NullPointerException。
<code class="language-kotlin">data class Person(val name: String, var age: Int)</code>
提示: 不建議使用此!!運算符,因為它違背了空安全的目的。
定義函數時,您可以指定參數是否可以為空。在這種情況下,調用者必須處理它。
<code class="language-java">Person p2 = new Person(p1.getName(), p1.getAge());</code>
有一個安全轉換運算符as?,如果轉換不可行,則返回null。
<code class="language-kotlin">val p2 = p1.copy(age = 42)</code>
您還可以在lambda表達式和高階函數中使用空安全功能:
<code class="language-java">String name = p1.getName(); int age = p1.getAge();</code>
let函數是一個作用域函數,允許您在非空對像上執行代碼塊。它通常用於以安全的方式在可空對像上執行代碼。
示例以及默認值:
<code class="language-kotlin">val (name, age) = p1 println(name) // "John" println(age) // 42</code>
Kotlin強烈鼓勵函數式編程風格!對於函數式編程風格,不可變性在避免錯誤方面起著至關重要的作用,尤其是在多線程應用程序中。
我現在可能要寫一篇關於Kotlin或Java中函數式編程的單獨文章,但現在讓我們關注不可變性。
Kotlin本質上更喜歡不可變對象而不是可變對象。這導致代碼更簡單、更可預測,尤其是在並發環境中。
在Kotlin中,使用val關鍵字聲明的變量默認情況下是不可變的。這與在Java中聲明final變量非常接近,但有一些關鍵區別:
示例:
<code class="language-kotlin">val name: String = "John" // 不可空 name = null // 编译错误!</code>
與Java的區別:在Java中,我們使用final關鍵字來確保變量不能重新賦值,但它指向的對象仍然可以是可變的。 Kotlin中的關鍵區別在於,不可變性默認情況下擴展到變量,這鼓勵為整個應用程序設計更可預測和更安全的方案。
可變變量示例:在Kotlin中使用var關鍵字允許您重新賦值變量。
<code class="language-java">public class Person { private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } // Getters, setters, ... }</code>
提示: Kotlin鼓勵盡可能使用val而不是var來確保不可變性。
默認情況下也鼓勵使用不可變集合。不可變集合防止在創建後進行任何修改,例如,如果您使用listOf()創建List,則不能更改它,不能添加、刪除或更改任何元素。
<code class="language-java">public record Person( String name, int age ) { }</code>
如果您需要修改集合,可以使用mutableListOf()或其他可變集合類型。
<code class="language-kotlin">data class Person(val name: String, var age: Int)</code>
與Java的區別:在Java中,集合(例如ArrayList)默認情況下是可變的,這意味著可以自由修改元素。
Kotlin的數據類默認情況下是不可變的。定義數據類時,屬性通常聲明為val,使類不可變。這使得類非常適合值對象,尤其是在處理API、數據庫記錄或任何其他對象狀態在創建後不應更改的場景時。
<code class="language-java">Person p2 = new Person(p1.getName(), p1.getAge());</code>
<code class="language-kotlin">val p2 = p1.copy(age = 42)</code>
Kotlin的密封類也可以是不可變的,並且它們與不可變數據模型配合良好。密封類通常用於表示受限的類層次結構,例如狀態或響應,並且它們的不可變性確保狀態或結果不會意外更改。
<code class="language-java">String name = p1.getName(); int age = p1.getAge();</code>
以上是Java開發人員Kotlin(第1部分)的詳細內容。更多資訊請關注PHP中文網其他相關文章!