【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-帅次";}//返回nullpublic String family(){return null;}
}
Kotlin 调用 Java 方法
fun main() {var user = JavaUser()println(user.userInfo())////使用时报错:NullPointerException
// println(user.family().length)//平台类型,可能为nullvar fam = user.family()//当fam为null时,fam?.length返回nullprintln(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 = 12println(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.jandkfun 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{@JvmFieldvar 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 = 178fun evaluate() = "SC是一个学习Kotlin的小渣渣"}
}
在kotlin中可直接使用,但是在Java中则必须
//在kotlin中可直接使用
fun main() {println(KotlinSc.height.toString().plus("CM"))//178CMprintln(KotlinSc.evaluate())//SC是一个学习Kotlin的小渣渣
}
//在Java中则相对复杂一些。public static void main(String[] args) {KotlinSc kotlinSc=new KotlinSc();System.out.println(kotlinSc.Companion.getHeight()+"CM");//178CMSystem.out.println(kotlinSc.Companion.evaluate());//SC是一个学习Kotlin的小渣渣}
给伴生对象的函数使用@JvmStatic注解,属性还是使用
class KotlinSc {...companion object{@JvmFieldvar height = 178@JvmStaticfun evaluate() = "SC是一个学习Kotlin的小渣渣"}
}
Java调用添加注解的函数和属性
public static void main(String[] args) {KotlinSc kotlinSc=new KotlinSc();System.out.println(KotlinSc.height+"CM");//178CMSystem.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.IOExceptione.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个)
【Kotlin 初学者】Java和Kotlin互操作相关推荐
- java:数字转string 报空指针_超干货详解:kotlin(4) java转kotlin潜规则
前言 以一个java老鸟的角度,如何去看 kotlin. Java源代码应该如何用Kotlin重构. 如何正确学习kotlin并且应用到实际开发中.本文将会探究. 本文分两大块,重难点和潜规则. 重难 ...
- java 可选参数_超干货详解:kotlin(4) java转kotlin潜规则
往期推荐 如果面试时大家都说真话... 这400道面试题,决定了你去BAT还是TMD 前言 以一个java老鸟的角度,如何去看 kotlin. Java源代码应该如何用Kotlin重构. 如何正确学习 ...
- Kotlin极简教程:第10章 Kotlin与Java互操作
Kotlin is 100% interoperable with Java™ and Android™ 在前面的章节中,我们已经学习了Kotlin的基础语法.类型系统.泛型与集合类.面向对象与函数式 ...
- java kotlin相互调用_Kotlin的互操作——Kotlin与Java互相调用
原标题:Kotlin的互操作--Kotlin与Java互相调用 互操作就是在Kotlin中可以调用其他编程语言的接口,只要它们开放了接口,Kotlin就可以调用其成员属性和成员方法,这是其他编程语言所 ...
- python kotlin_在Python,Java和Kotlin中标记参数和重载
python kotlin 在多种语言之间跳来跳去可以帮助您注意到不同语言的习惯用法和最佳做法之间的某些差异. 比较有趣的差异之一与一个函数执行多项操作有关. Python 我们先来看一下Python ...
- 在Python,Java和Kotlin中标记参数和重载
在多种语言之间跳来跳去可以帮助您注意到不同语言的习惯用法和最佳做法之间的某些差异. 比较有趣的差异之一与一个函数执行多项操作有关. Python 我们先来看一下Python. Python实际上无法重 ...
- kotlin 调用java_从Kotlin调用Java代码
Kotlin代码与Java代码完全兼容. Java代码在Kotlin代码中轻松调用,Kotlin代码也可以通过Java代码的正常方式调用. 从Kotlin调用Java代码 从Kotlin文件调用Jav ...
- 从Java到Kotlin(三)
本篇文章主要对比Java跟Kotlin中的类和接口的写法. 目录 一.类的声明 二.构造函数 三.函数的参数 四.创建类的实例 五.数据类 六.枚举类 七.属性 八.内部类 九.可见性修饰符 十.继承 ...
- 从Java到Kotlin(五)
函数与Lambda表达式 目录 一.函数声明与调用 二.参数和返回值 三.单表达式函数 四.函数作用域 五.泛型函数 六.尾递归函数 七.中缀表示法 八.Lambda表达式的语法 九.高阶函数与Lam ...
- 【Kotlin】apply 内联扩展函数 ( apply 函数原型 | apply 函数示例 | Kotlin 调用 Java API )
文章目录 I . 内联扩展函数 apply II . Kotlin 调用 Java API III . apply 内联扩展函数示例 ( 调用 Java API 处理图像 ) I . 内联扩展函数 a ...
最新文章
- java -jar 和 -cp详解
- python文件读read()、readline()、readlines()对比
- input的type为number
- [你必须知道的.NET] 第一回:恩怨情仇:is和as
- 【Python】Matplotlib绘制极坐标螺旋线图
- elementui上传图片加参数_Vue + Element UI使用富文本编辑器
- iOS连续上传多张图片
- java如何写ajax,java,jq,ajax写分页
- c语言做线性代数第六版答案,线性代数求解(C语言):
- 【Android】常用对话框大全(一)Android Dialog
- pytorch 入门教程 常用知识整理
- 二级域名指向同一ip的不同端口
- 如何把分布式远程总线IO应用到项目中
- java 正整数类型_Java 整数类型
- SAP PO Delivery Address的决定因素
- 验证码短信收不到的原因及解决办法
- Flutter开发之——Icon图标
- 1.2 租车系统(前台+后台)----成果图
- php显示星期几,php怎么实现获取显示星期几
- ISO 27001 2022 中文版 范围
热门文章
- 简直太猛了!GitHub《植物大战僵尸》重磅开源,两天就破千Star!
- 2018年SCI论文--整合GEO数据挖掘完整复现 八 :STRING数据库构建蛋白质相互作用网络(PPI),cytoscape软件筛选hub基因
- [乐意黎转载]一个治愈 JavaScript 疲劳的学习计划
- 图论、建图--bzoj1539: [POI2005]Dwu-Double-row
- 史上最全RabbitMq详解
- ESXI-vCenter-NSX-系统虚拟化
- L2-4 彩虹瓶 (25 分)-2019天梯赛全国总决赛
- HR直言:这几类求职者不会要!
- axios 和洋葱模型中间件
- java基础之 IO流