kotlin 和java 混编

2023-05-16

如果你之前使用 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() 

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


   
  1. var s = some?.s ?: ""

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

  3. var list = some?.data?.list:klist

  4. 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 中使用了这些关键字,需要加上反引号(`)转义来避免冲突。例如


   
  1. // Java 代码中有个方法叫 is()

  2. public void is(){

  3. //...

  4. }

  5.  
  6. // 转换为 Kotlin 代码需要加反引号转义

  7. fun `is`() {

  8. //...

  9. }

3.3 在 Java 中调用 Kotlin 代码

3.3.1 static 方法

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


   
  1. StringUtils.isEmpty("hello");

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

  3.  
  4. object StringUtils {

  5. @JvmStatic fun isEmpty(str: String): Boolean {

  6. return "" == str

  7. }

  8.  
  9. fun isEmpty2(str: String): Boolean {

  10. return "" == str

  11. }

  12. }

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


   
  1. class StringUtils {

  2. companion object {

  3. fun isEmpty(str: String): Boolean {

  4. return "" == str

  5. }

  6. }

  7. }

companion object表示外部类的一个伴生对象,你可以把他理解为外部类自动创建了一个对象作为自己的field
与上面的类似,Java 在调用时,可以这样写:StringUtils.Companion.isEmpty();(1.1以后可以省略中间的 Companion,写作 StringUtils.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 和java 混编 的相关文章

  • Java中有没有一种方法可以通过名称实例化一个类?

    我正在寻找问题 从字符串名称实例化一个类 https stackoverflow com questions 9854900 instantiate an class from its string name它描述了如何在有名称的情况下实例
  • 如何循环遍历所有组合,例如48 选择 5 [重复]

    这个问题在这里已经有答案了 可能的重复 如何在java中从大小为n的集合中迭代生成k个元素子集 https stackoverflow com questions 4504974 how to iteratively generate k
  • 为 java 游戏创建交互式 GUI

    大家好 我正在创建一个类似于 java 中的 farmville 的游戏 我只是想知道如何实现用户通常单击以与游戏客户端交互的交互式对象 按钮 我不想使用 swing 库 通用 Windows 看起来像对象 我想为我的按钮导入自定义图像 并
  • 动态选择端口号?

    在 Java 中 我需要获取端口号以在同一程序的多个实例之间进行通信 现在 我可以简单地选择一些固定的数字并使用它 但我想知道是否有一种方法可以动态选择端口号 这样我就不必打扰我的用户设置端口号 这是我的一个想法 其工作原理如下 有一个固定
  • HSQL - 识别打开连接的数量

    我正在使用嵌入式 HSQL 数据库服务器 有什么方法可以识别活动打开连接的数量吗 Yes SELECT COUNT FROM INFORMATION SCHEMA SYSTEM SESSIONS
  • Pig Udf 显示结果

    我是 Pig 的新手 我用 Java 编写了一个 udf 并且包含了一个 System out println 其中的声明 我必须知道在 Pig 中运行时该语句在哪里打印 假设你的UDF 扩展了 EvalFunc 您可以使用从返回的 Log
  • 在 Jar 文件中运行 ANT build.xml 文件

    我需要使用存储在 jar 文件中的 build xml 文件运行 ANT 构建 该 jar 文件在类路径中可用 是否可以在不分解 jar 文件并将 build xml 保存到本地目录的情况下做到这一点 如果是的话我该怎么办呢 Update
  • 在接口中使用默认方法是否违反接口隔离原则?

    我正在学习 SOLID 原则 ISP 指出 客户端不应被迫依赖于他们所使用的接口 不使用 在接口中使用默认方法是否违反了这个原则 我见过类似的问题 但我在这里发布了一个示例 以便更清楚地了解我的示例是否违反了 ISP 假设我有这个例子 pu
  • 来自 dll 的 Java 调用函数

    我有这个 python 脚本导入zkemkeeperdll 并连接到考勤设备 ZKTeco 这是我正在使用的脚本 from win32com client import Dispatch zk Dispatch zkemkeeper ZKE
  • java.lang.IllegalStateException:应用程序 PagerAdapter 更改了适配器的内容,而没有调用 PagerAdapter#notifyDataSetChanged android

    我正在尝试使用静态类将值传递给视图 而不是使用意图 因为我必须传递大量数据 有时我会收到此错误 但无法找出主要原因是什么 Error java lang IllegalStateException The application s Pag
  • 帮助将图像从 Servlet 获取到 JSP 页面 [重复]

    这个问题在这里已经有答案了 我目前必须生成一个显示字符串文本的图像 我需要在 Servlet 上制作此图像 然后以某种方式将图像传递到 JSP 页面 以便它可以显示它 我试图避免保存图像 而是以某种方式将图像流式传输到 JSP 自从我开始寻
  • volatile、final 和synchronized 安全发布的区别

    给定一个带有变量 x 的 A 类 变量 x 在类构造函数中设置 A x 77 我们想将 x 发布到其他线程 考虑以下 3 种变量 x 线程安全 发布的情况 1 x is final 2 x is volatile 3 x 设定为同步块 sy
  • Java ResultSet 如何检查是否有结果

    结果集 http java sun com j2se 1 4 2 docs api java sql ResultSet html没有 hasNext 方法 我想检查 resultSet 是否有任何值 这是正确的方法吗 if resultS
  • java for windows 中的文件图标叠加

    我正在尝试像 Tortoise SVN 或 Dropbox 一样在文件和文件夹上实现图标叠加 我在网上查了很多资料 但没有找到Java的解决方案 Can anyone help me with this 很抱歉确认您的担忧 但这无法在 Ja
  • 关键字“table”附近的语法不正确,无法提取结果集

    我使用 SQL Server 创建了一个项目 其中包含以下文件 UserDAO java public class UserDAO private static SessionFactory sessionFactory static se
  • 我如何在java中读取二进制数据文件

    因此 我正在为学校做一个项目 我需要读取二进制数据文件并使用它来生成角色的统计数据 例如力量和智慧 它的设置是让前 8 位组成一个统计数据 我想知道执行此操作的实际语法是什么 是不是就像读文本文件一样 这样 File file new Fi
  • 插件“Android Bundle Support”不兼容

    大家好 自从上次更新以来 当我启动 android studio 时 我遇到了一个非常奇怪的错误 我有这个错误 插件错误 插件 Android Bundle Support 不兼容 直到构建 AI 195 SNAPSHOT 我在网上找不到任
  • 包 javax.el 不存在

    我正在使用 jre6 eclipse 并导入 javax el 错误 包 javax el 不存在 javac 导入 javax el 过来 这不应该是java的一部分吗 谁能告诉我为什么会这样 谢谢 米 EL 统一表达语言 是 Java
  • 如何将双精度/浮点四舍五入为二进制精度?

    我正在编写对浮点数执行计算的代码的测试 不出所料 结果很少是准确的 我想在计算结果和预期结果之间设置一个容差 我已经证实 在实践中 使用双精度 在对最后两位有效小数进行四舍五入后 结果始终是正确的 但是usually四舍五入最后一位小数后
  • 双枢轴快速排序和快速排序有什么区别?

    我以前从未见过双枢轴快速排序 是快速排序的升级版吗 双枢轴快速排序和快速排序有什么区别 我在 Java 文档中找到了这个 排序算法是双枢轴快速排序 作者 弗拉基米尔 雅罗斯拉夫斯基 乔恩 本特利和约书亚 布洛赫 这个算法 在许多数据集上提供

随机推荐

  • C#修改文件或文件夹的权限,为指定用户、用户组添加完全控制权限

    写在前面 在windows系统中 xff0c c盘中的目录权限比较高 xff0c 有时制作安装包的时候 xff0c 默认的安装路径就是在c盘 xff0c 但对运行可执行文件 xff0c 有时候需要为其添加完全控制权限 xff0c 或者读写权
  • ASP.NET简易教程-页面布局

    页面布局 网上有太多介绍 xff0c 个人觉得不错的有 Div 43 CSS布局大全 xff0c 有PDF版本 xff0c 可下载离线观看 xff0c 别人总结的一个文档 xff0c 简洁易懂 xff0c 学起来不费劲 xff0c 花时间不
  • File.Create创建文件后,需要释放…

    if File Exists SavePath File Create SavePath Close
  • 最全CSS各种布局详解

    一 单列布局的实现 1 单列布局中最常用的水平居中的四种方法 同时设置父元素和子元素的样式 xff1a 父元素使用text align实现 xff0c 子元素使用inline block 这里宽高背景只是为了展示 parent text a
  • Android开发的之基本控件和详解四种布局方式

    Android中的控件的使用方式和iOS中控件的使用方式基本相同 xff0c 都是事件驱动 给控件添加事件也有接口回调和委托代理的方式 今天这篇博客就总结一下Android中常用的基本控件以及布局方式 说到布局方式Android和iOS还是
  • 为Android Studio中的SettingsActivity定制任务栏 (Setting Activity其实本质上是从PreferenceActivity中继承过来的)

    Android Studio为开发者提供了很多内建的Activity 其中Settings Activity是非常有用且功能强大的一种内建Activity Setting Activity其实本质上是从PreferenceActivity中
  • Android设置页面PreferenceFragment使用详细+代码分析

    Android设置页面PreferenceFragment使用详细 文章目录Android设置页面PreferenceFragment使用详细一 设置页面核心代码二 设置页面布局核心代码三SettingFragment核心代码四 setti
  • Android Studio 上Activity的互相切换

    Activity上有两个按钮 xff0c 切换到其他两个Activity 1 先创建两个Button xff0c 一个Textview 2 给两个Button添加监听器 xff0c 实现如下代码 public class MainActiv
  • Android中的Intent和Intent-filter总结

    一 xff0e 相关概念 xff08 一 xff09 基本概念 Intent中文意思指 意图 按照Android的设计理念 Android使用Intent来封装程序的 调用意图 不管启动Activity Service BroadcastR
  • C#接口中为什么不能像java那样使用static?

    我印象中java里面的接口使用static final修饰的常量 xff0c 不是成员方法 xff0c 使用static修饰的method放在接口中是无意义的 xff0c 接口是用来抽象的 与Java不同 xff0c C 中的接口不能包含域
  • JVM(2)九个部分 p4

    文章目录 1 九大部分1 1 类加载子系统1 2 方法区1 3 堆1 4 直接内存1 5 jvm栈1 6 本地方法栈1 7 垃圾回收系统1 8 PC寄存器1 9 执行引擎 2 堆 栈 方法区的联系3 Java堆的不同结构4 对象已经死了吗4
  • 通过点击事件监听 setOnClickListener 彻底理解回调-Android

    前言 老司机们对于回调肯定熟悉得不能再熟悉了 但是新司机可能还是一脸懵逼的 xff0c 我比较笨 xff0c 当年懵逼了好久 xff0c 看夏安明的这一篇博客地址 xff0c 虽然下边的留言都是 xff0c 写得好 xff01 懂了懂了 x
  • Java 接口和抽象类可以被new么?——顺便总结内部类

    转载 xff1a https blog csdn net hackersaillen article details 47281549 背景 xff1a 最近有同事跟我说了他面试时遇到的问题 xff0c 考官问 xff1a 接口和抽象类可以
  • java之方法的重写

    方法的重写 xff1a 1 在子类中可以根据需要对从基类中继承来的方法进行重写 2 重写的方法和被重写的方法必须具有相同方法名称 参数列表和返回类型 3 重写方法不能使用比被重写的方法更严格的访问权限 程序code class Person
  • Android中传递对象的三种方法

    Android中 xff0c Activity和Fragment之间传递对象 xff0c 可以通过将对象序列化并存入Bundle或者Intent中进行传递 xff0c 也可以将对象转化为JSON字符串 xff0c 进行传递 序列化对象可以使
  • Android中BroadCastReceiver使用(整理)

    BroadcastReceiver 在Android中 xff0c Broadcast是一种广泛运用的在应用程序之间传输信息的机制 而BroadcastReceiver是对发送出来的 Broadcast进行过滤接受并响应的一类组件 下面将详
  • Android的联通性---USB主机模式(三)

    获取跟设备通信的权限 在跟USB设备进行通信之前 xff0c 你的应用程序必须要获取用户的许可 注意 xff1a 如果你的应用程序使用Intent过滤器来发现接入的USB设备 xff0c 而且用户允许你的应用程序处理该Intent xff0
  • android USB

    google 在推出API 3 0后 就增加啦USB通讯这块 同时为API 2 3提供啦一个USB通讯吧 xff0c 这样也让2 3有啦USB通讯功能 不过只支持USBAccessory模式 USB通讯分为两种模式 xff1a xff08
  • 入门 Kotlin 和 Java 混合开发

    一 前沿 如果你学习过其他的编程语言 xff0c 你就会发现 Java 的语法很是哆嗦 xff0c 可是我们为什么没有放弃 Java 这门编程语言呢 xff1f 因为 JVM 是一个非常好的平台 xff0c 而且 Java 程序员目前在中国
  • kotlin 和java 混编

    如果你之前使用 Java 语言而没有 Kotlin 开发经验 xff0c 不用担心 xff0c Intellij IDEA 会帮你一键转换 xff0c 将 Java 代码转换成 Kotlin 代码 但是反过来就不行了 在 Mac 上 xff