Android 之 kotlin 語言學習筆記三(Kotlin-Java 互操作)

參考官方文檔:https://developer.android.google.cn/kotlin/interop?hl=zh-cn

一、Java(供 Kotlin 使用)

1、不得使用硬關鍵字

不要使用 Kotlin 的任何硬關鍵字作為方法的名稱 或字段。允許使用 Kotlin 的軟關鍵字、修飾符關鍵字和特殊標識符。

  • 硬關鍵字
    as、as?、break、class、continue、do、else、 false、for、fun、if、in、!in、interface、is、!is、null、object、package、super、this、throw、true、typealias、typeof、val、var、when、while。

  • 軟關鍵字、修飾符關鍵字和特殊標識符
    https://kotlinlang.org/docs/keyword-reference.html#hard-keywords

2、避免使用 Any 的擴展函數或屬性的名稱

3、可為 null 性注釋

  • 公共 API 中的每個非基礎參數類型、返回類型和字段類型都應 具有可為 null 性注解。
  • 未加注解的類型會被解釋為 “平臺”類型,這些類型是否可為 null 性不明確。

4、Lambda 參數位于最后

  • 符合 SAM 轉換條件的參數類型應位于最后。例如,RxJava 2 的 Flowable.create() 方法簽名定義為:
	public static <T> Flowable<T> create(FlowableOnSubscribe<T> source,BackpressureStrategy mode) { /* … */ }// 在 kotlin 中調用時顯示為Flowable.create({ /* … */ }, BackpressureStrategy.LATEST)
  • 如果方法簽名中的參數顛倒順序,則函數會調用 可以使用尾隨 lambda 語法:
	public static <T> Flowable<T> create(BackpressureStrategy mode,FlowableOnSubscribe<T> source) { /* … */ }// 在 kotlin 中調用時顯示為Flowable.create(BackpressureStrategy.LATEST) { /* … */ }

5、屬性前綴

  • 對于在 Kotlin 中要表示為屬性的方法,需要嚴格的**“bean”樣式** 前綴。
  • 訪問器方法需要 get 前綴;對于布爾值返回方法,則為 is 前綴。
  • 更改器方法需要 set 前綴
  • 如果希望方法作為屬性公開,請不要使用非標準前綴,例如 has、set 或無 get 前綴的訪問器。帶有非標準前綴的方法 也可作為函數進行調用,具體取決于 方法的行為。
	public final class User {public String getName() { /* … */ }public void setName(String name) { /* … */ }public boolean isActive() { /* … */ }public void setActive(boolean active) { /* … */ }}// 對應的 kotlin 代碼val name = user.name // Invokes user.getName()val active = user.isActive // Invokes user.isActive()user.name = "Bob" // Invokes user.setName(String)user.isActive = true // Invokes user.setActive(boolean)

6、運算符過載

  • 允許特殊調用點語法。
	public final class IntBox {private final int value;public IntBox(int value) {this.value = value;}public IntBox plus(IntBox other) {return new IntBox(value + other.value);}}// kotlin 代碼val one = IntBox(1)val two = IntBox(2)val three = one + two // Invokes one.plus(two)

二、Kotlin(供 Java 使用)

1、文件名

  • 如果文件包含頂級函數或屬性,請始終為其添加注解 使用 @file:JvmName(“Foo”) 提供一個好記的名稱。
  • 默認情況下,MyClass.kt 文件中的頂級成員最終將位于名為 MyClassKt 文件中,該名字沒有吸引力,并且會泄露作為實現的語言 。
  • 建議您添加“@file:JvmMultifileClass”,它是 Kotlin 中的一個注解,用于支持將一個 Kotlin 文件拆分成多個部分,這些部分在 Java 中被視為同一個類的一部分。
  • 使用 @file:JvmMultifileClass 注解時,通常會結合 @file:JvmName 注解來指定生成的 Java 類的名稱。這樣,多個 Kotlin 文件可以合并成一個 Java 類,而不會出現命名沖突。

2、Lambda 參數

  • 使用 Java 定義的單一方法接口 (SAM) 可以用 Kotlin 語言實現,也可以使用 lambda 語法的 Java 語言以慣用方式內嵌實現。

(1)首選定義

  • 要在 Java 中使用的高階函數,不應接受會返回 Unit 的函數類型,而建議使用功能 (SAM) 接口
  • 即使函數類型不會返回 Unit,仍建議您將其設為命名接口,以便調用方使用命名類來實現它,而非只使用 lambda(在 Kotlin 和 Java 中)。
  • 在定義預期用作 lambda 的接口時,優先考慮使用功能 (SAM) 接口,而不是常規接口 ,用以支持 Kotlin 中的慣用用法。
	// 高階函數,函數類型為 (String) -> Unitfun sayHi(greeter: (String) -> Unit)// 建議使用 SAM 接口fun interface GreeterCallback {fun greetName(String name)}fun sayHi(greeter: GreeterCallback) = /* … */// kotlin 中調用sayHi { println("Hello, $it!") }// java 中調用sayHi(name -> System.out.println("Hello, " + name + "!"));// 實現接口的命名類class MyGreeterCallback : GreeterCallback {override fun greetName(name: String) {println("Hello, $name!");}}

(2)避免使用會返回 Unit 的函數類型

  • 返回 Unit 的函數類型要求 Java 調用方返回 Unit.INSTANCE
	// kotlinfun sayHi(greeter: (String) -> Unit) = /* … */// 對應的 java 調用sayHi(name -> {System.out.println("Hello, " + name + "!");return Unit.INSTANCE;});

(3)如果接口實現持有狀態,請避免使用功能接口

  • 當接口實現需要持有狀態時,使用 lambda 語法是沒有意義的。Comparable 是一個典型的例子,因為它需要比較 this 和 other,而 lambda 表達式沒有 this不使用 fun 修飾接口會迫使調用者使用 object : … 語法,這允許實現中持有狀態,同時也為調用者提供了一個提示。
  • 不使用 fun 修飾的接口無法在 Kotlin 中使用 lambda 語法。
	// No "fun" prefix.interface Counter {fun increment()}runCounter(object : Counter {private var increments = 0 // State	override fun increment() {increments++}})

3、避免使用 Nothing 類屬

  • 泛型參數為 Nothing 的類型會作為原始類型提供給 Java。原始 類型在 Java 中很少使用,應予以避免使用。

4、防御性復制

  • 在從公共API返回共享的或無主的只讀集合時,應將其包裝在一個不可修改的容器中,或者執行防御性拷貝。盡管Kotlin強制執行了它們的只讀屬性,但Java端并沒有這樣的強制性。如果沒有包裝器或防御性拷貝,返回一個長期存在的集合引用可能會破壞不變性。

5、伴生函數

  • 伴生對象中的公共函數必須帶有 @JvmStatic 注解使其公開為靜態方法,如果沒有該注解,這些函數在 Java 中只能作為實例方法使用。
	// 不正確,沒有 @JvmStatic 注解class KotlinClass {companion object {fun doWork() {/* … */}}}// 在 java 中調用public final class JavaClass {public static void main(String... args) {KotlinClass.Companion.doWork();}}// 正確,添加 @JvmStatic 注解class KotlinClass {companion object {@JvmStatic fun doWork() {/* … */}}}// 在 java 中調用public final class JavaClass {public static void main(String... args) {KotlinClass.doWork();}}

6、伴生常量

  • 作為 companion object 中的有效常量的公共非 const 屬性必須帶有 @JvmField 注解,java 調用時才能作為靜態字段提供。
  • 如果沒有該注解,這些屬性只能作為靜態Companion字段上奇怪命名的實例“getter”方法使用。
  • 而使用@JvmStatic替代@JvmField,則會將這些奇怪命名的“getter”方法移動到類的靜態方法中,但這仍然是不正確的。
	// 1、不正確,沒有注解class KotlinClass {companion object {const val INTEGER_ONE = 1val BIG_INTEGER_ONE = BigInteger.ONE}}// java 中調用public final class JavaClass {public static void main(String... args) {System.out.println(KotlinClass.INTEGER_ONE);System.out.println(KotlinClass.Companion.getBIG_INTEGER_ONE());}}// 2、不正確:@JvmStatic 注釋class KotlinClass {companion object {const val INTEGER_ONE = 1@JvmStatic val BIG_INTEGER_ONE = BigInteger.ONE}}// java 中調用public final class JavaClass {public static void main(String... args) {System.out.println(KotlinClass.INTEGER_ONE);System.out.println(KotlinClass.getBIG_INTEGER_ONE());}}//3、正確:@JvmField 注釋class KotlinClass {companion object {const val INTEGER_ONE = 1@JvmField val BIG_INTEGER_ONE = BigInteger.ONE}}// java 中調用public final class JavaClass {public static void main(String... args) {System.out.println(KotlinClass.INTEGER_ONE);System.out.println(KotlinClass.BIG_INTEGER_ONE);}}

7、符合語言習慣的命名

  • Kotlin 的調用規范與 Java 不同,這可能會改變您為函數命名的方式。使用 @JvmName 設計符合語言習慣的名稱 或匹配各自的標準庫 命名。
  • 擴展函數和擴展屬性最常出現這種情況 因為接收器類型的位置不同。
	sealed class Optional<T : Any>data class Some<T : Any>(val value: T): Optional<T>()object None : Optional<Nothing>()@JvmName("ofNullable")fun <T> T?.asOptional() = if (this == null) None else Some(this)// FROM KOTLIN:fun main(vararg args: String) {val nullableString: String? = "foo"val optionalString = nullableString.asOptional()}// FROM JAVA:public static void main(String... args) {String nullableString = "Foo";Optional<String> optionalString =Optionals.ofNullable(nullableString);}

8、默認值的函數過載

  • 參數具有默認值的函數必須使用 @JvmOverloads。如果沒有此注解,則無法使用任何默認值來調用函數。
  • 在使用@JvmOverloads時,要檢查生成的方法,確保每個方法都合理。如果它們不合理,請執行以下一種或兩種重構操作,直到滿意為止:
    • 調整參數順序,將帶有默認值的參數放在最后
    • 將默認值移入手動實現的函數重載中。
	 // 不正確:沒有 @JvmOverloadsclass Greeting {fun sayHello(prefix: String = "Mr.", name: String) {println("Hello, $prefix $name")}}// java 調用public class JavaClass {public static void main(String... args) {Greeting greeting = new Greeting();greeting.sayHello("Mr.", "Bob");}}// 正確:@JvmOverloads 注釋class Greeting {@JvmOverloadsfun sayHello(prefix: String = "Mr.", name: String) {println("Hello, $prefix $name")}}// java 調用public class JavaClass {public static void main(String... args) {Greeting greeting = new Greeting();greeting.sayHello("Bob");}}

三、Lint 檢查

  • 在 Android 開發中,Lint 檢查 是一種靜態代碼分析工具,用于檢查代碼中的潛在問題,幫助開發者在編譯之前發現并修復代碼中的錯誤、性能問題、安全問題、可維護性問題等。

1、環境要求

  • Android Studio 版本:3.2 Canary 10 或更高版本
  • Android Gradle 插件版本:3.2 或更高版本

2、支持的檢查

  • 支持的檢查包括:
    • 未知 Null 性
    • 屬性訪問
    • 不得使用 Kotlin 硬關鍵字
    • Lambda 參數位于最后

3、Android Studio 中啟用檢查

  • Android Studio 中要啟用這些檢查,請依次點擊 File > Settings >Editor >Inspections,在 “Android Lint: Interoperability” 下選中您要啟用的規則。
  • 選中要啟用的規則后,新的檢查將 在運行代碼檢查 (Code > Inspect Code…) 時運行。

在這里插入圖片描述

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/84391.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/84391.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/84391.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

從 GreenPlum 到鏡舟數據庫:杭銀消費金融湖倉一體轉型實踐

作者&#xff1a;吳岐詩&#xff0c;杭銀消費金融大數據應用開發工程師 本文整理自杭銀消費金融大數據應用開發工程師在StarRocks Summit Asia 2024的分享 引言&#xff1a;融合數據湖與數倉的創新之路 在數字金融時代&#xff0c;數據已成為金融機構的核心競爭力。杭銀消費金…

Bean 作用域有哪些?如何答出技術深度?

導語&#xff1a; Spring 面試繞不開 Bean 的作用域問題&#xff0c;這是面試官考察候選人對 Spring 框架理解深度的常見方式。本文將圍繞“Spring 中的 Bean 作用域”展開&#xff0c;結合典型面試題及實戰場景&#xff0c;幫你厘清重點&#xff0c;打破模板式回答&#xff0c…

基于 Spring Boot 策略模式的短信服務提供商動態切換實現

一、整體設計思路 為了實現在短信服務提供商變更時,不修改現有代碼就能無縫切換到新服務實現,可采用策略模式結合依賴注入以及配置中心化管理的方式來設計軟件系統。 二、 具體實現步驟 1. 定義統一接口(以短信服務為例,接口命名為 SmsService) 創建一個抽象的接口,用…

解決SQL Server SQL語句性能問題(9)——SQL語句改寫(1)

9.4. SQL語句改寫 目前主流關系庫的高版本中,特別是作為主流商業關系庫的SQL Server來講,大部分場景中,同一語義和結果集的SQL語句,其不同寫法并不會影響CBO為SQL語句生成和選擇最合適、最高效的查詢計劃。但少數情況下,不同寫法的同一語義和結果集的SQL語句,CBO也許會為…

設計模式復習小結

1.容易忘得設計原則 接口隔離&#xff1a;指接口中的功能太雜則可以拆分一下。防止實現類實現了接口后自動依賴了一些不需要的功能。不同功能拆分成不同的接口。 里氏代換&#xff1a;強調父類能出現的地方&#xff0c;子類一定能正常跑。 迪米特法則&#xff1a;又稱最少知…

昇騰CANN集合通信技術解讀——細粒度分級流水算法

隨著AI技術的演進&#xff0c;模型的計算復雜度和參數量呈現幾何級數增長&#xff0c;這使得傳統單機單卡部署在算力供給與顯存容量方面顯得力不從心&#xff0c;從而直接推動了分布式訓練/推理技術的快速發展。今年年初爆火的DeepSeek在訓練及推理Prefill階段采用了分級流水Al…

水泥廠自動化升級利器:Devicenet轉Modbus rtu協議轉換網關

在水泥廠的生產流程中&#xff0c;工業自動化網關起著至關重要的作用&#xff0c;尤其是JH-DVN-RTU疆鴻智能Devicenet轉Modbus rtu協議轉換網關&#xff0c;為水泥廠實現高效生產與精準控制提供了有力支持。 水泥廠設備眾多&#xff0c;其中不少設備采用Devicenet協議。Devicen…

使用Matplotlib創建炫酷的3D散點圖:數據可視化的新維度

文章目錄 基礎實現代碼代碼解析進階技巧1. 自定義點的大小和顏色2. 添加圖例和樣式美化3. 真實數據應用示例實用技巧與注意事項完整示例(帶樣式)應用場景在數據科學和可視化領域,三維圖形能為我們提供更豐富的數據洞察。本文將手把手教你如何使用Python的Matplotlib庫創建引…

Copilot for Xcode (iOS的 AI輔助編程)

Copilot for Xcode 簡介Copilot下載與安裝 體驗環境要求下載最新的安裝包安裝登錄系統權限設置 AI輔助編程生成注釋代碼補全簡單需求代碼生成輔助編程行間代碼生成注釋聯想 代碼生成 總結 簡介 嘗試使用了Copilot&#xff0c;它能根據上下文補全代碼&#xff0c;快速生成常用…

React 進階特性

1. ref ref 是 React 提供的一種機制,用于訪問和操作 DOM 元素或 React 組件的實例。它可以用于獲取某個 DOM 元素的引用,從而執行一些需要直接操作 DOM 的任務,例如手動設置焦點、選擇文本或觸發動畫。 1.1. 使用 ref 的步驟 1. 創建一個 ref:使用 React.createRef 或 …

基于PHP的連鎖酒店管理系統

有需要請加文章底部Q哦 可遠程調試 基于PHP的連鎖酒店管理系統 一 介紹 連鎖酒店管理系統基于原生PHP開發&#xff0c;數據庫mysql&#xff0c;前端bootstrap。系統角色分為用戶和管理員。 技術棧 phpmysqlbootstrapphpstudyvscode 二 功能 用戶 1 注冊/登錄/注銷 2 個人中…

【大廠機試題解法筆記】報文響應時間

題目 IGMP 協議中&#xff0c;有一個字段稱作最大響應時間 (Max Response Time) &#xff0c;HOST收到查詢報文&#xff0c;解折出 MaxResponseTime 字段后&#xff0c;需要在 (0&#xff0c;MaxResponseTime] 時間 (s) 內選取隨機時間回應一個響應報文&#xff0c;如果在隨機…

邏輯回歸暴力訓練預測金融欺詐

簡述 「使用邏輯回歸暴力預測金融欺詐&#xff0c;并不斷增加特征維度持續測試」的做法&#xff0c;體現了一種逐步建模與迭代驗證的實驗思路&#xff0c;在金融欺詐檢測中非常有價值&#xff0c;本文作為一篇回顧性記錄了早年間公司給某行做反欺詐預測用到的技術和思路。百度…

Python爬蟲實戰:研究demiurge框架相關技術

1. 引言 在當今數字化時代,互聯網上蘊含著海量的有價值信息。爬蟲技術作為獲取這些信息的重要手段,被廣泛應用于學術研究、商業分析、輿情監測等多個領域。然而,構建一個高效、穩定且可維護的爬蟲系統面臨諸多挑戰,如網頁結構復雜多變、反爬機制日益嚴格、數據處理流程繁瑣…

Jenkins | Jenkins構建成功服務進程關閉問題

Jenkins構建成功服務進程關閉問題 1. 原因2. 解決 1. 原因 Jenkins 默認會在構建結束時終止所有由構建任務啟動的子進程&#xff0c;即使使用了nohup或后臺運行符號&。 2. 解決 在啟動腳本中加上 BULID_IDdontkillme #--------------解決jenkins 自動關閉進程問題-----…

深度學習習題2

1.如果增加神經網絡的寬度&#xff0c;精確度會增加到一個特定閾值后&#xff0c;便開始降低。造成這一現象的可能原因是什么&#xff1f; A、即使增加卷積核的數量&#xff0c;只有少部分的核會被用作預測 B、當卷積核數量增加時&#xff0c;神經網絡的預測能力會降低 C、當卷…

猜字符位置游戲-position gasses

import java.util.*;public class Main {/*字符猜位置游戲;每次提交只能被告知答對幾個位置;根據提示答對的位置數推測出每個字符對應的正確位置;*/public static void main(String[] args) {char startChar A;int gameLength 8;List<String> ballList new ArrayList&…

解析兩階段提交與三階段提交的核心差異及MySQL實現方案

引言 在分布式系統的事務處理中&#xff0c;如何保障跨節點數據操作的一致性始終是核心挑戰。經典的兩階段提交協議&#xff08;2PC&#xff09;通過準備階段與提交階段的協調機制&#xff0c;以同步決策模式確保事務原子性。其改進版本三階段提交協議&#xff08;3PC&#xf…

Towards Open World Object Detection概述(論文)

論文&#xff1a;https://arxiv.org/abs/2103.02603 代碼&#xff1a;https://github.com/JosephKJ/OWOD Towards Open World Object Detection 邁向開放世界目標檢測 Abstract 摘要 Humans have a natural instinct to identify unknown object instances in their environ…

QT3D學習筆記——圓臺、圓錐

類名作用Qt3DWindow3D渲染窗口容器QEntity場景中的實體&#xff08;對象或容器&#xff09;QCamera控制觀察視角QPointLight點光源QConeMesh圓錐幾何網格QTransform控制實體的位置/旋轉/縮放QPhongMaterialPhong光照材質&#xff08;定義顏色、反光等&#xff09;QFirstPersonC…