Kotlin Primer·第三章·Kotlin 与 Java 混编

2023-11-03

虽然 Kotlin 的开发很方便,但当你与他人协作时,总会碰到 Java 与 Kotlin 代码共存的代码项目。
本章就教你如何优雅的实现 Kotlin 与 Java 混合编程。

3.1 直接转换

3.1.1 将 Java 转换为 Kotlin

如果你之前使用 Java 语言而没有 Kotlin 开发经验,不用担心,Intellij IDEA 会帮你一键转换,将 Java 代码转换成 Kotlin 代码(但是反过来就不行了)。
在 Mac 上,系统默认的快捷键为control+shift+command+K,这个组合键实在有点反人类,建议你自定义一个你觉得舒服的快捷键。
快捷键可以通过你的编译器 keymap 中修改:command+, -> 搜索keymap -> 右侧搜索kotlin,可以查看到Convert Java File to Kotlin File项。

图3-1-1

3.1.2 注意 Class 调用

在 Java 或 Android 开发中,经常会直接调用一个类的 Class 文件。但是当你用上文介绍的转换方法去转换 XXX.class这样的代码时,是无法直接转换的(也许未来会修复这个问题,但目前你扔需要手动修改)。在 M13 之前,Java 中的XXX.class对应 Kotlin 代码中的JavaClass<XXX>,而 M13 之后写法已被改为XXX::class.java

3.1.3 Android proguard 的坑

注:我们团队遇到过这样的一个坑,在 Android 开发的时候,如下代码会在混淆以后,发生异常

var str = some?.s?.d ?: ""

这段代码在正常debug模式编译运行完全正常,但是一旦执行混淆,就会发生所在函数被移除的现象。
但是如果改写为以下写法就能正常运行:

var str = some?.s?.d ?: String()

猜想应该是 proguard 不知道如何处理这段代码,无法识别出最后两个引号是一个String,最后直接将整个函数移除掉了。

同样的代码还有:

var list = some?.data?.list:mutableListof() 

但是如下代码即使混淆后也是可以完全正常执行的

var s = some?.s ?: ""  
var s = some.d ?: ""
var list = some?.data?.list:klist  
var data = some?.data ?: return

3.1.4 开发 Android library 的建议

如果你是开发 Android library 程序,建议你不要使用 Kotlin 代码。因为作为 library,如果使用它的工程是纯 Java 完成的,引入后会额外增大 200k 左右大小,同时它有可能会造成某些情况下编译异常。

3.2 在 Kotlin 中调用 Java 代码

3.2.1 返回 void 的方法

如果一个 Java 方法返回 void,对应的在 Kotlin 代码中它将返回 Unit。关于 Unit,本书将在 第五章函数部分着重讲解。 
现在你只需要知道在Java 中返回为 void 的函数,在 Kotlin 中可以省略这个返回类型。

3.2.2 与 Kotlin 关键字冲突的处理

Java 有 static 关键字,在 Kotlin 中没有这个关键字,你需要使用@JvmStatic替代这个关键字。
同样,在 Kotlin 中也有很多的关键字是 Java 中是没有的。例如 in,is,data等。如果 Java 中使用了这些关键字,需要加上反引号(`)转义来避免冲突。例如

// Java 代码中有个方法叫 is()
public void is(){
	//...
}

// 转换为 Kotlin 代码需要加反引号转义
fun `is`() {
   //...
}

3.3 在 Java 中调用 Kotlin 代码

3.3.1 static 方法

上文已经提到过,在 Kotlin 中没有 static关键字,那么如果在 Java 代码中想要通过类名调用一个 Kotlin 类的方法,你需要给这个方法加入@JvmStatic注解。否则你必须通过对象调用这个方法。

StringUtils.isEmpty("hello");  
StringUtils.INSTANCE.isEmpty2("hello");

object StringUtils {
    @JvmStatic fun isEmpty(str: String): Boolean {
        return "" == str
    }

    fun isEmpty2(str: String): Boolean {
        return "" == str
    }
}

如果你阅读 Kotlin 代码,应该经常看到这样一种写法。

class StringUtils {
    companion object {
       fun isEmpty(str: String): Boolean {
	        return "" == str
	    }
    }
}

companion object表示外部类的一个伴生对象,你可以把他理解为外部类自动创建了一个对象作为自己的field
与上面的类似,Java 在调用时,可以这样写:StringUtils.Companion. isEmpty();
关于伴生对象,我们将在下一章 类与对象 详细讲解。

3.3.2 包级别函数

与 Java 不同,Kotlin 允许函数独立存在,而不必依赖于某个类,这类函数我们称之为包级别函数(Package-Level Functions)。
为了兼容 Java,Kotlin 默认会将所有的包级别函数放在一个自动生成的叫ExampleKt的类中, 在 Java 中想要调用包级别函数时,需要通过这个类来调用。 
当然,也是可以自定义的,你只需要通过注解@file:JvmName("Example")即可将当前文件中的所有包级别函数放到一个自动生成的名为 Example 的类中。

3.3.3 空安全性

在 Java 中,如果你调用的 kotlin 方法参数声明了非空类型,如果你在 Java 代码中传入一个空值,将在运行时抛出NullPointerException。其内部原因在于 Kotlin 为每个非空类型加了断言,如果传入空值则会立刻抛出异常。 
同样,如果你使用 null 对象去调用一个 kotlin 方法,将会立刻抛出NullPointerException(就算是调用普通 java 方法也是一样会抛出 NullPointerException )

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Kotlin Primer·第三章·Kotlin 与 Java 混编 的相关文章

  • JSP中的内置对象pageContext的作用

    1 当作当前页面域对象使用 2 可以获取到jsp中其他8个内置对象 jsp中其实可以直接用其他内置对象 但再el表达式中可以尝试使用 因为request response session servletContext servletConf
  • 小程序-报错 xxx is not defined (已解决)

    小程序 报错 xxx is not defined 已解决 问题情境 这样一段代码 微信的小程序报错 is not defined 我 wxml 想这样调用 wxml 代码
  • 力扣每日一题【用户分组】

    题目链接 用户分组 视频连接 用户分组 C 代码 class Solution public vector
  • CTO六大能力模型

    一个公司的CTO面临着许多难题和尴尬处境 他们整天忙得焦头烂额 跟CEO肩并肩共同应对各种困难 他们跟其它高管紧密配合 提供强大的技术后盾 他们不断学习新技术 制定符合企业的技术战略 想要成为一名优秀的CTO 究竟要具备哪些方面的能力素质
  • 如何评估大型语言模型(LLM)?

    编者按 近期几乎每隔一段时间 就有新的大语言模型发布 但是当下仍然没有一个通用的标准来评估这些大型语言模型的质量 我们急需一个可靠的 综合的LLM评估框架 本文说明了为什么我们需要一个全面的大模型评估框架 并介绍了市面上这些现有的评估框架
  • 地址解析协议 (ARP)

    地址解析协议 ARP 是互联网协议 IP 套件的关键第 2 层协议 可将 IP 地址转换为媒体访问控制 MAC 地址 IP MAC ARP 在实现网络连接方面发挥着不可或缺的作用 能够发现本地网络上设备的硬件地址并将其映射到其 IP 地址
  • STM32F429 不断重复复位

    之前做过一块STM32F429的板子 板子搭载SDRAM和NAND flash 刚开始板子还是好好的 用了一段时间之后 板子变得很奇怪 开机后SDRAM和NAND初始化之后 运行SDRAM的测试代码 大概运行10S左右就会出现一次复位 我在
  • html设置一段文字颜色,用span css设置div内部分字体颜色

    用span标签设置div内放一段文字中的一小部分文字字体色采方式 一段笔墨放在DIV内或P内 当咱们配置div或p设置字体色彩 内里全体笔墨的字体色调就会变成咱们所配置字体色彩 通常会结构一段翰墨中个中几个字或一小块字的字体色采不同 此时就
  • Hibernate学习(2)- hibernate.cfg.xml详解

    1 主配置文件主要分为三部分 注意 通常情况下 一个session factory节点代表一个数据库 1 1 第一部分 数据库连接部分 注意 hibernate connection driver class 中间的 1 2 第二部分 其他
  • LintCode 202. Segment Tree Query (线段树经典题!)

    Segment Tree Query 中文English For an integer array index from 0 to n 1 where n is the size of this array in the correspon
  • 玩转ChatGPT:视频制作

    一 写在前面 最近 在码深度学习图像识别的相关知识和代码 这一part 看看能否用小Chat搞一个介绍视频 简单问小Chat 咒语 我怎么使用你做一个视频 需要配合什么软件生成 大意就是 惊呆了 这不是我想要的 还是先半自动 后全自动吧 二
  • flink启动报错Failed to construct kafka producer

    flink local模式下启动 sink2kafka报错 具体报错如下 apache kafka common KafkaException Failed to construct kafka producer at org apache
  • python谁是卧底、猜词语

    python谁是卧底 谁是卧底也是深受很多人喜欢的游戏 起码要三人以上才能玩 大致分为几个阶段 1 分配平民词语和卧底词语 gt 2 玩家依次发言 gt 3 根据发言投票认为谁是卧底 gt 4 得到票数最多的玩家出局 gt 5 出局玩家刚好
  • 网络安全—攻防

    招聘需求 尝试通过收集招聘平台的相关职业岗位描述DJ 进行相关方面能力学习 攻防安全 认证 TCSP证书 CISM证书 CISP证书 CISSP证书 CISP PTE证书 CISP DSG证书 CISP A证书 CISD证书 CCSRP证书
  • 2020-10-14 KIBANA7 配置(搜索、可视化组件和仪表板)导出导入

    需求描述 线上Kibana的可视化图表跟仪表盘配置意外丢失了 还好测试环境有相同的配置 根据Kibana的功能进行配置的导出 gt 导入 避免手工一个一个重新配置的繁琐跟配置错误疏漏等情况 也同时进行下配置文件的导出备份工作 参考资料 官方
  • 好分数阅卷3.0_自考阅卷老师是怎么打分的?

    距离十月自考还有一个月 又到了全国考生转发考神的时间 但还有一招更有用 解密阅卷老师 往年很多同学查分后 都会有这么几个疑问 在答题的时候 感觉每道题都答得不错 为什么分数只有这么点 56 57这种分数 搞不懂老师为什么就不能多给我几分 俗
  • Matlab如何打包成jar并给java使用(混合编程)

    Matlab如何打包成jar并给java使用 由于期末数字图像课程设计需求 使用matlab码好了函数可是没有界面 所以打算用jsp随便搞一搞 可是这样就要跨语言编程了 说得很高大上其实就是打成jar然后丢到项目lib包里面去 这时就需要打
  • H5——连连看小游戏实现思路及源码

    部门要求推广新产品用连连看小游戏的方式 设计那边UI还没有排期 先撸个功能demo 正好记录一下 连连看都玩过 程序的关键在于判断连续点击的两张图片是否能够消除 两个图片消除的条件有两个 图片相同 两张图之间连线的转角数不超过2 第一个条件
  • 高级纹理映射技术(6)

    高级纹理映射技术 6 对一些特殊的应用需要对纹理坐标进行处理 主要包括纹理坐标自动生成和纹理坐标变换 下图显示了纹理坐标的来源 处理过程以及到达光栅处理器的过程 纹理坐标自动生成 在Direct3D程序中 不仅可以在模型载入阶段或渲染阶段指

随机推荐

  • EPICS asynPortDriver中数组用法示例

    本驱动程序是继承自asynPortDriver 分别重写了用于读取32位整型数组和32位浮点型数组的 readInt32Array和readFloat32Array 1 源代码如下 arraydriver h include epicsEv
  • 30道软件测试高频面试题

    如果哪个测试经理在看我的文章 希望对面试者要微笑 不然面试结束 出门之后就一万个草泥马奔腾而过 其实面试者并不是希望你给他们什么 而是一种尊重 平等的谈话 不要高高在上感觉自己超牛逼一样 任何大牛都是从菜鸟起步的 当然 正在学习测试技术的人
  • VUE之Vxe-table动态生成多级表头

    需求 1 第一列为正常列 2 第二列开始为动态生成列 根据接口返回数据生成 3 最后一列为编辑列 实现步骤 模板中定义
  • Java 类的主动使用和被动使用

    Java程序对类的使用方式分为 主动使用和被动使用 主动使用 又分为七种情况 1 创建类的实例 2 访问某个类或者接口的静态变量 或者对该静态变量赋值 3 反射 比如 Class forName java lang String 4 初始化
  • 代码漏洞说明

    1 代码注入 命令注入 命令注入是指 在应用程序执行的命令中包含来源于不可信数据时 程序本身没有对这些不可信数据做正确 合理的验证和过滤 导致系统执行恶意命令 例1 以下代码通过Runtime exec 方法调用Windows的dir命令
  • PID简介

    一 基本定义 Sv 用户设定值 给定信号 Pv 控制对象当前状态值 反馈信号 E 偏差值 偏差信号 所以 E Sv Pv 二 PID各个控制基本分析 1 P控制 比例控制 Pout Kp Ek 假定从早上开机上电 我们每隔一秒钟就通过传感器
  • html5的session,HTML5 sessionStorage会话存储

    sessionStorage 是HTML5新增的一个会话存储对象 用于临时保存同一窗口 或标签页 的数据 在关闭窗口或标签页之后将会删除这些数据 本篇主要介绍 sessionStorage 会话存储 的使用方式 包括添加 修改 删除等操作
  • c++语言的学习——判断闰年

    判断闰年 描述 判断某年是否是闰年 输入 输入只有一行 包含一个整数a 0 lt a lt 3000 输出 一行 如果公元a年是闰年输出Y 否则输出N 样例输入 2006 样例输出 N 提示 公历纪年法中 能被4整除的大多是闰年 但能被10
  • Wireshark的两种过滤器与BPF过滤规则

    Wirshark使用的关键就在于过滤出想要的数据包 下面介绍怎么过滤 抓包过滤器 Wirshark有两种过滤器 一个是抓包过滤器 一个是显示过滤器 他们之间的区别在于抓包过滤器只抓取你设置的规则 同时丢弃其他信息 显示过滤器并不会丢弃信息
  • Qt之UDP通信

    目录 一 UDP简介 二 QUdpSocket类 三 UDP服务器 四 UDP客户端 五 代码 1 udp服务端 2 udp客户端 一 UDP简介 UDP User Datagram Protocol 即用户数据报协议 是一个轻量级的 不可
  • 如何使用Jekyll在GitHub Pages上搭建网站(个人博客)

    前言 本文很长 建议使用侧边栏进行跳转 Jekyll 是一个基于 Ruby 语言的 用于搭建静态网站的生成器 主要用于搭建博客网站 官方自己的介绍为 Jekyll is a blog aware static site generator
  • “error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed”解决方法

    使用git通过https方式从github clone git repo源码时 报错如下 1 2 3 Cloning into git fatal unable to access https github com git git git
  • 【用JS自制表格软件玩数据】8. 设计单元格中的右键菜单

    右键菜单选项的设计 效果图 基本数据 分析 功能 菜单的渲染模块 右键菜单的样式 最终结果 当写完本系列后 我会把源代码分享出来给大家 本课程也会持续更新与矫正 欢迎留言指正 效果图 基本数据 首先构建一个基本的配置数据 property
  • 【历史上的今天】1 月 9 日:iPhone 问世;iTunes 发布;激光打印机的发明者出生

    整理 王启隆 透过 历史上的今天 从过去看未来 从现在亦可以改变未来 今天是 2023 年 1 月 9 日 在 1978 年的这段时间 我国恢复了研究生制度 这一年 共录取了 10500 多名研究生 研究生教育的中断和复兴是一个漫长的过程
  • Linux中利用docker搭建深度学习环境

    写在前面 在深度学习中 避免不了在远程服务器上进行模型的训练 如果直接在服务器裸机的基础环境跑显然是不可取的 此时搭建用于模型训练的docker环境显得尤为重要 1 下载基础镜像 选择一个合适的基础镜像会给后续的操作带来极大的便利 其中uf
  • centos7安装redis

    文章目录 一 准备工作 二 安装redis 三 配置redis 四 配置redis服务 五 其他 一 准备工作 关闭防火墙等 linux时间校对 试验环境 虚拟机服务器版本 centos7 虚拟机IP地址 192 168 1 10 win端
  • uniapp在H5获取当前定位信息不需要SDK可直接获取城市(包括经纬度省市区和市区编码)

    前言 最近在做获取用户当前定位信息的时候 发现uniapp官方提供的uni getLocation OBJECT 兼容性并不是特别好 光注意事项都是密密麻麻一大堆 在实际使用场景下 效果并不理想 也不是很稳定 于是便重新封装了一下腾讯地图的
  • JUC-多线程(5.获得线程的第三种方式)学习笔记

    文章目录 获得线程的第三种方式 Callable接口 1 前言 1 获得多线程的方法几种 2 以下两种获得线程的方式的异同 2 使用 1 重写 call 方法 2 创建线程 3 获取返回值 3 原理 1 简述 2 解释 3 结论 获得线程的
  • 关于加速度计读数与加速度方向的问题

    近几日对加速计读数的正负与其敏感轴 实际加速度计方向的关系又产生了诸多疑问 参考这篇博文的一个模型后 更是混乱了 http www geek workshop com forum php mod viewthread tid 1695 re
  • Kotlin Primer·第三章·Kotlin 与 Java 混编

    虽然 Kotlin 的开发很方便 但当你与他人协作时 总会碰到 Java 与 Kotlin 代码共存的代码项目 本章就教你如何优雅的实现 Kotlin 与 Java 混合编程 3 1 直接转换 3 1 1 将 Java 转换为 Kotlin