首頁 > Java > java教程 > Java開發人員Kotlin(第1部分)

Java開發人員Kotlin(第1部分)

Mary-Kate Olsen
發布: 2025-01-27 16:04:17
原創
883 人瀏覽過

Kotlin for Java Developers (Part 1)

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記錄和Kotlin資料類別都是不可變的資料載體。
  • 在Java中,欄位隱含為final,在建構後無法修改,而在Kotlin中,您可以透過使用val或var來選擇是否要使欄位可變。
  • 另一個區別是,Java中的記錄類隱式為final和sealed,這意味著它們不能被擴展,而在Kotlin中,您可以擴展資料類。
  • 在Kotlin中,您還可以覆寫equals、hashCode和toString方法,這在Java中是不可能的。
  • Kotlin開箱即用地提供了一個copy方法,這在Java中是不可用的。

一些例子:

在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資料類
  • Baeldung:Kotlin資料類

利用空安全

在我看來,Kotlin中的空安全是最強大的功能之一。這是一個改變遊戲規則的功能,可以節省您大量的時間和麻煩。在Kotlin中,空安全內建於類型系統中,這使得更容易避免與空相關的運行時錯誤。

1. 可空型

在Kotlin中,可空類型是明確聲明的。這意味著您可以擁有一個可能保存空值的變量,但您必須在聲明中明確指定它。

不可空型別(預設行為)

預設情況下,Kotlin中的所有類型都是不可空的,這表示變數不能保存空值。

<code class="language-kotlin">val name: String = "John" // 不可空
name = null // 编译错误!</code>
登入後複製
登入後複製

可空型

要聲明一個可以保存空值的變量,您必須使用?運算符。

<code class="language-kotlin">val name: String? = null // 可空</code>
登入後複製

2. 安全呼叫

一個強大的功能是安全呼叫運算子?.。它允許您安全地呼叫方法或存取屬性,而不會拋出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。

3. Elvis運算符(?:)

Elvis運算符?:是如果運算符左側的表達式為空則返回默認值的簡寫。

<code class="language-java">public record Person(
    String name,
    int age
) {
}</code>
登入後複製
登入後複製
登入後複製

4. !!運算符(非空斷言)

您可以使用!!運算符告訴編譯器該值不為空。如果該值為null,它將拋出NullPointerException。

<code class="language-kotlin">data class Person(val name: String, var age: Int)</code>
登入後複製
登入後複製
登入後複製

提示: 不建議使用此!!運算符,因為它違背了空安全的目的。

5. 函數參數中的可空性

定義函數時,您可以指定參數是否可以為空。在這種情況下,調用者必須處理它。

<code class="language-java">Person p2 = new Person(p1.getName(), p1.getAge());</code>
登入後複製
登入後複製
登入後複製

6. 安全轉換(as?運算符)

有一個安全轉換運算符as?,如果轉換不可行,則返回null。

<code class="language-kotlin">val p2 = p1.copy(age = 42)</code>
登入後複製
登入後複製
登入後複製

7. lambda表達式中的空安全

您還可以在lambda表達式和高階函數中使用空安全功能:

<code class="language-java">String name = p1.getName();
int age = p1.getAge();</code>
登入後複製
登入後複製
登入後複製

8. 利用let函數

let函數是一個作用域函數,允許您在非空對像上執行代碼塊。它通常用於以安全的方式在可空對像上執行代碼。

示例以及默認值:

<code class="language-kotlin">val (name, age) = p1
println(name) // "John"
println(age) // 42</code>
登入後複製
登入後複製

9. 最佳實踐

  • 避免使用!!運算符
  • 使用安全調用和Elvis運算符安全地處理可空類型並提供默認值
  • 僅在必要時才使用可空類型

參考:

  • Kotlin空安全

默認情況下不可變性

Kotlin強烈鼓勵函數式編程風格!對於函數式編程風格,不可變性在避免錯誤方面起著至關重要的作用,尤其是在多線程應用程序中。

我現在可能要寫一篇關於Kotlin或Java中函數式編程的單獨文章,但現在讓我們關注不可變性。

Kotlin本質上更喜歡不可變對象而不是可變對象。這導致代碼更簡單、更可預測,尤其是在並發環境中。

1. 默認情況下不可變的變量(val)

在Kotlin中,使用val關鍵字聲明的變量默認情況下是不可變的。這與在Java中聲明final變量非常接近,但有一些關鍵區別:

  • Kotlin中的val變量實際上是只讀的——在初始化後不能更改分配給它的值。
  • 但是,如果該值是一個對象,則仍然可以修改該對象的屬性,除非這些屬性本身聲明為val。

示例:

<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來確保不可變性。

2. 不可變集合

默認情況下也鼓勵使用不可變集合。不可變集合防止在創建後進行任何修改,例如,如果您使用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)默認情況下是可變的,這意味著可以自由修改元素。

3. 不可變數據類

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>
登入後複製
登入後複製
登入後複製

4. 密封類中的不可變性

Kotlin的密封類也可以是不可變的,並且它們與不可變數據模型配合良好。密封類通常用於表示受限的類層次結構,例如狀態或響應,並且它們的不可變性確保狀態或結果不會意外更改。

<code class="language-java">String name = p1.getName();
int age = p1.getAge();</code>
登入後複製
登入後複製
登入後複製

以上是Java開發人員Kotlin(第1部分)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板