IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> 【Kotlin 初学者】Java和Kotlin互操作 -> 正文阅读

[移动开发]【Kotlin 初学者】Java和Kotlin互操作

作者简介:CSDN博客专家、华为云·云享专家认证

系列专栏:Kotlin 初学者

五星好评:左侧点一下(网页端),移动端:https://bbs.csdn.net/topics/603956616

目录

一、Kotlin调用Java

1.1 互操作性与可空性

1.2 类型映射

1.3 属性访问

二、Java调用Kotlin

2.1 @JvmName

2.2 @JvmField

2.3 @JvmStatic

2.4 @JvmOverloads

2.4.1 未使用@JvmOverloads注解

2.4.2 使用@JvmOverloads注解

2.5 @Throws

2.6 函数类型操作


一、Kotlin调用Java

1.1 互操作性与可空性

????????Java世界里所有对象都是null,当一个Kotlin函数返回String类型值,它是可空的。

建立一个 Java 类

class?JavaUser?{
????public?String?userInfo(){
????????return?"Java-帅次";
????}
????//返回null
????public?String?family(){
????????return?null;
????}
}

Kotlin 调用 Java 方法

fun?main()?{
????var?user?=?JavaUser()
????println(user.userInfo())//
????//使用时报错:NullPointerException
//????println(user.family().length)

????//平台类型,可能为null
????var?fam?=?user.family()
????//当fam为null时,fam?.length返回null
????println(fam?.length)//null
}

1.2 类型映射

????????代码运行时,所有的映射类型都会重新映射回对应的Java类型。

Java定义属性类型

class?JavaUser?{
????public?String?name?=?"Java";
????...
}

Kotlin 查看类型

fun?main()?{
????println(user.name.javaClass)//查看类型:class?java.lang.String
}

1.3 属性访问

????????刚才使用public修饰属性,在Kotlin可以直接调用,那么我们用private呢?

Java定义属性

class?JavaUser?{
????private?int?age?=18;

????public?int?getAge()?{
????????return?age;
????}

????public?void?setAge(int?age)?{
????????this.age?=?age;
????}
????...
}

Kotlin 使用

fun?main()?{
????println(user.age)
????user.age?=?12
????println(user.age)
????println(user.age.javaClass)
}

????????如果仅使用private而不设置get/set方法 Kotlin是无法调用的,当设置了get/set方法。Kotlin可以直接调用其属性,而不用调用get/set方法(默认调用get/set方法),如下图:

二、Java调用Kotlin

2.1 @JvmName

????????可以使用JvmName注解指定编译类的名字。

2.1.1 在KotlinUser文件中定义kotlinUserInfo()函数

package?com.scc.kotlin.primary.jandk

fun?kotlinUserInfo()?=?"来自Kotlin的招呼"

2.1.2 在JavaMain使用main方法调用Kotlin的kotlinUserInfo()函数

package?com.scc.kotlin.primary.jandk;

class?JavaMain?{
????public?static?void?main(String[]?args)?{
????????System.out.println(KotlinUserKt.kotlinUserInfo());//来自Kotlin的招呼
????}
}

????????觉得KotlinUserKt不好看,咱们给它换个名字,或者说起个别名。

2.1.3 在Kotlin文件最上方添加@JvmName

????????这个必须写在文件最顶部。

@file:JvmName("SCKotlin")
package?com.scc.kotlin.primary.jandk
fun?kotlinUserInfo()?=?"来自Kotlin的招呼"

2.1.4 调用@JvmName设置的名字

????public?static?void?main(String[]?args)?{
//????????System.out.println(KotlinUserKt.kotlinUserInfo());//来自Kotlin的招呼
????????System.out.println(SCKotlin.kotlinUserInfo());//来自Kotlin的招呼
????}

2.2 @JvmField

????????在Java里,不能直接访问Kotlin定义的字段(如下:name),所以必须调用getName,然而,你可以给Kotlin属性添加@JvmField注解,暴露它的支持字段给Java调用者,从而避免使用getter方法。

class?KotlinSc{
????@JvmField
????var?name?=?"Kotlin-SC"
????var?age?=?13
}

????????KotlinSc的name属性添加了@JvmField注解,Java可以直接调用,age属性未添加@JvmField注解,所以Java无法直接调用,当然你可以通过get/set方法调用age属性。如下图:

class?JavaMain?{
????public?static?void?main(String[]?args)?{
????????KotlinSc?kotlinSc=new?KotlinSc();
????????System.out.println(kotlinSc.name);//Kotlin-SC
????}
}

2.3 @JvmStatic

????????对函数使用该注解,kotlin编译器将生成另一个静态方法;

????????对属性使用该注解,kotlin编译器将生成其他的setter和getter方法;

????????这个注解的作用其实就是消除Java调用Kotlin的companion object对象时不能直接调用其静态方法和属性的问题.

注意:此注解只能在companion object中使用

class?KotlinSc?{
????...
????//伴生对象
????companion?object{
????????var?height?=?178
????????fun?evaluate()?=?"SC是一个学习Kotlin的小渣渣"
????}
}

在kotlin中可直接使用,但是在Java中则必须

//在kotlin中可直接使用
fun?main()?{
????println(KotlinSc.height.toString().plus("CM"))//178CM
????println(KotlinSc.evaluate())//SC是一个学习Kotlin的小渣渣
}
//在Java中则相对复杂一些。
????public?static?void?main(String[]?args)?{
????????KotlinSc?kotlinSc=new?KotlinSc();
????????System.out.println(kotlinSc.Companion.getHeight()+"CM");//178CM
????????System.out.println(kotlinSc.Companion.evaluate());//SC是一个学习Kotlin的小渣渣

????}

给伴生对象的函数使用@JvmStatic注解,属性还是使用

class?KotlinSc?{
????...
????companion?object{
????????@JvmField
????????var?height?=?178
????????@JvmStatic
????????fun?evaluate()?=?"SC是一个学习Kotlin的小渣渣"
????}
}

Java调用添加注解的函数和属性

????public?static?void?main(String[]?args)?{
????????KotlinSc?kotlinSc=new?KotlinSc();
????????System.out.println(KotlinSc.height+"CM");//178CM
????????System.out.println(KotlinSc.evaluate());//SC是一个学习Kotlin的小渣渣

????}

2.4 @JvmOverloads

????????JvmOverloads注解协助产生Kotlin函数的重载版本。设计一个可能会暴露给Java用户使用的API时,记得使用@JvmOverloads注解,这样,无论你是Kotlin开发者还是Java开发者,都会对这个API的可靠性感到满意。

2.4.1 未使用@JvmOverloads注解

????????定义一个未使用@JvmOverloads注解的Kotlin函数

fun?kotlinEat(bread:?String?=?"巧克力面包",?meat:?String?=?"鸡翅")?{
????println("$bread-搭配-$meat-美极了")
}

????????使用kotlin调用,一点问题没有,妥妥的。

fun?main()?{
????kotlinEat();//巧克力面包-搭配-鸡翅-美极了
????kotlinEat("橙香面包")//橙香面包-搭配-鸡翅-美极了
????kotlinEat(meat?=?"羊肉")//巧克力面包-搭配-羊肉-美极了
????kotlinEat("奶油长杆面包","牛肉")//奶油长杆面包-搭配-牛肉-美极了
}

????????使用Java调用,仅能调用传入两个参数的方法,而不能像Kotlin那样随意调用。

2.4.2 使用@JvmOverloads注解

????????我们在给kotlinEat(bread: String = "巧克力面包", meat: String = "鸡翅")函数添加@JvmOverloads注解。

@JvmOverloads
fun?kotlinEat(bread:?String?=?"巧克力面包",?meat:?String?=?"鸡翅")?{
????println("$bread-搭配-$meat-美极了")
}

????public?static?void?main(String[]?args)?{
????????SCKotlin.kotlinEat("Java牌面包");//Java牌面包-搭配-鸡翅-美极了

????}

????????为什么会这样?咱们看看:

????????未使用@JvmOverloads注解

????????使用@JvmOverloads注解,此处截图不全,两个参数的方法没截取到,感兴趣的自己去玩玩。

????????使用@JvmOverloads注解后强迫该函数重载,这样Java就可以进行不同场景调用了。

2.5 @Throws

????????使用@Throws注解,声明这个方法要检查Exception。

//这里的Throws是必须添加的,要不Java那边无法捕捉这个异常
@Throws(IOException::class)
fun?kotlinEatException(){
????println("吃东西呛住了")
????throw?IOException()
}

????????编译成Java代码,如下:

????public?static?void?main(String[]?args)?{
????????try?{
????????????SCKotlin.kotlinEatException();//吃东西呛住了
????????}?catch?(IOException?e)?{
????????????System.out.println(e);//java.io.IOException
????????????e.printStackTrace();
????????}
????}

2.6 函数类型操作

????????函数类型和匿名函数能提供高效的语法用于组件间的交互,是Kotlin编程语言里比较新颖的特性。

????????他们简洁的语法因->操作符而实现,但Java8之前的JDK版本并并不支持lambda表达式。

????????在Java里,Kotlin函数类型使用FunctionN这样的名字的接口来表示的,FunctionN中的N代表值参数目。这样的Function接口从Function0到Function22(23个),每一个FunctionN都包含一个invoke函数,专用于调用函数类型函数,所以,任何时候需要调一个函数类型,都用它调用invoke。

val?hair?=?{colorHair:String?->
????println(?"头发染成?$colorHair?即可")
}

val?hairTwo?=?{colorHair:String,lengthHair:Int?->
????println(?"头发染成$colorHair,剪至$lengthHair-厘米即可")
}
????????Function1<String,?Unit>?hair?=?SCKotlin.getHair();
????????hair.invoke("红色");//头发染成?红色?即可
????????Function2<String,?Integer,?Unit>?hairTwo?=?SCKotlin.getHairTwo();
????????hairTwo.invoke("蓝色",8);//头发染成蓝色,剪至8-厘米即可

Function接口从Function0到Function22(23个)

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2022-01-03 16:13:34  更:2022-01-03 16:15:58 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 9:33:45-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码