Java调用Kotlin程序深度解析
异常:
在之前我们已经学习在Kotlin中的所有异常都是运行期的,而不像Java分为运行期和非运行期,下面用代码来演示一下,先建一个Java的异常:

然后在Kotlin中来调用一下该Java中的方法

很明显IOException在Java是需要检查的异常,然后在Kotlin中居然是不需要进行异常处理,而在运行时肯定就抛出异常了:

在Kotlin中获取Java类型:
另外在Kotlin中如何来获取它具体Java对应的类型呢,可以如下:


还有另外一种方式也可以获取:

其中可以看一下它的定义:

Java调用Kotlin:
对于Kotlin怎么来调用Java已经学习了,而接下来反着来用一下,这要稍复杂一下,下面开始:
属性(properties):
一个Kotlin属性会被编译为3部分元素:
1、一个getter方法。
2、一个setter方法。
3、一个私有的字段(field),其名字与Kotlin的属性名一样。
下面来定义一个论证一下上面的理论:

如何来论证呢?当然得反编译啦:

此时需要再加一个参数才能看到,如下:

但是需要注意一点:如果Kotlin属性名以is开头,那么命名的约定会发生一些变化,具体如下:
1、getter方法名与属性名一样。
2、setter方法名则将is替换为set。
3、一个私有的字段(field),其名字与Kotlin的属性名一样。
这种规则适用于任何类型,而不单单是Boolean类型。
下面再来验证一下此理论:

方法:
我们知道在Kotlin中的方法可以不属于任何类,如下:

但是很明显它不符合Java的规则,而最终都会编译成jvm字节码肯定得遵照Java的规则,所以下面来研究一下它的机理,先看代码:

咱们再来新建一个Java文件,来调用Kotlin:
首先来调用我们在Kotlin定义的MyClass,其实直接可以使用,如下:

那么。。接下来再调用我们在Kotlin定义的test()和str问题就来了,它是依附于哪个类中的呢?我们先来看一下我们的HelloKotlin2.kt编译成了啥?

其实就是用它来可以直接调用,其中test()和str变成了该类的静态方法和属性,所以可以直接通过类名来调用它们俩,如下:

好,下面再来一探这个Kotlin在字节码的表现,进一步来加深在Java调用Kotlin的用法:
xiongweideMacBook-Pro:kotlin_lecture xiongwei$ javap -c -p com/kotlin/test11/HelloKotlin2Kt.class
Compiled from "HelloKotlin2.kt"
public final class com.kotlin.test11.HelloKotlin2Kt {
private static java.lang.String str; public static final void test();
Code:
0: ldc #8 // String hello world
2: astore_0
3: iconst_0
4: istore_1
5: getstatic #14 // Field java/lang/System.out:Ljava/io/PrintStream;
8: aload_0
9: invokevirtual #20 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
12: return public static final java.lang.String getStr();
Code:
0: getstatic #27 // Field str:Ljava/lang/String;
3: areturn public static final void setStr(java.lang.String);
Code:
0: aload_0
1: ldc #31 // String <set-?>
3: invokestatic #37 // Method kotlin/jvm/internal/Intrinsics.checkParameterIsNotNull:(Ljava/lang/Object;Ljava/lang/String;)V
6: aload_0
7: putstatic #27 // Field str:Ljava/lang/String;
10: return static {};
Code:
0: ldc #54 // String hello
2: putstatic #27 // Field str:Ljava/lang/String;
5: return
}
那既然生成的类是HelloKotlin2Kt,那是不是我们可以直接来生成它的实例呢?下面试试:

貌似木有问题,那运行一下呗:

为啥呢?那我们看一下字节码中看一下,确实是木有生成构造方法。。好奇怪,对于普通的Java类编译生成的字节码肯定会生成一个构造方法,所以总结如下:“我们是无法通过new关键字来创建Kotlin编译器自动生成的以Kt结尾的类的实例的,因为Kotlin编译器在生成的字节码中没有不带参数的构造方法。”
这是跟Java存在很大差别的,也违背了我们一贯的认知,所以需要非常注意!!!
Java调用Kotlin程序深度解析的更多相关文章
- Java 8 Optional 类深度解析
Java 8 Optional 类深度解析 身为一名Java程序员,大家可能都有这样的经历:调用一个方法得到了返回值却不能直接将返回值作为参数去调用别的方法.我们首先要判断这个返回值是否为null,只 ...
- Java调用Kotlin事项及Kotlin反射初步
继续来研究Java调用Kotlin的一些东东. @Throws注解: 我们知道在Kotlin中是不存在checked exception的,而在Java中是存在的,那..如果从Java来调用Kotli ...
- java调用python程序以及向python程序传递参数
在做项目的时候,经常会碰到这个问题,主要程序是用java写的,有些功能使用python写的,整个项目需要把java代码和python代码进行整合,在一个项目里面运行,这就涉及到java调用python ...
- Java调用Python程序
最近,需要在应用中,需要使用Java程序去调用Python代码,主要有两种实现方式. 一.使用Jython架包 因为调用的Python代码中需要使用Json对象,开始使用jython2.5.2,发现不 ...
- Runtime.getRuntime().exec()实现Java调用python程序
使用Runtime.getRuntime().exec()来实现Java调用python,调用代码如下所示: import java.io.BufferedReader; import java.io ...
- 类型擦除对Java调用Kotlin的影响
@JvmName: 扩展方法相关: 先来定义一个扩展方法: 好,接下来再来定义一个扩展函数: 此时报错了..看一下错误提示: 其中给的提示有点奇怪,第一个是很明显咱们的扩展函数木有接收参数嘛,为啥提示 ...
- Java基础常用类深度解析(包含常见排序算法)
目录 一.工具类 1.1.工具类的设计 1.1.1.公共静态方法 1.2.单例模式 二.包装类 2.1.基本类型的包装类 2.1.1.Integer 2.1.1.1.Integer >> ...
- Java 8 Optional类深度解析
身为一名Java程序员,大家可能都有这样的经历:调用一个方法得到了返回值却不能直接将返回值作为参数去调用别的方法.我们首先要判断这个返回值是否为null,只有在非空的前提下才能将其作为其他方法的参数. ...
- JAVA 调用exe程序执行对应的文件 (个人用于编译Java文件)
需求: 需要利用Java程序,来调用计算机本身的黑窗口,来将特定的Java文件编译成对应的字节码文件. 实现思路: 通过调用Java的Runtime类,每个 Java 应用程序都有一个 Runtime ...
随机推荐
- web端测试总结
1.数值型输入框: 条件:demcial(x,y) ,界面显示小数点到y位 通常要检查以下几点: (1)边界值:最大值.最小值.最大值+1.最小值-1 (2)位数:最小位数.最大位数.最小位数-1最 ...
- Putty——支持Telnet,ssh连接的连接软件
简介 PuTTY 的官方网站:http://www.chiark.greenend.org.uk/~sgtatham/putty/,截止到 2007年6月,发布的最高稳定版本是 0.6.PuTTY 是 ...
- DFS BFS 学习总结
DFS 深度优先搜索 基本思路: if(true) 返回 典型例题: 1.马走日(非常典型) #include<iostream> #include<cstring> usin ...
- DRF框架(一)——restful接口规范、基于规范下使用原生django接口查询和增加、原生Django CBV请求生命周期源码分析、drf请求生命周期源码分析、请求模块request、渲染模块render
DRF框架 全称:django-rest framework 知识点 1.接口:什么是接口.restful接口规范 2.CBV生命周期源码 - 基于restful规范下的CBV接口 3.请求组件 ...
- Python之路【第十二篇】:Python面向对象高级
一.反射 1 什么是反射 反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问.检测和修改它本身状态或行为的一种能力(自省).这一概念的提出很快引发了计算机科学领域关于应用反射性的研究 ...
- JAVA知识点总结篇(一)
JVM(Java Virtual Machine):源文件->编译器->字节码文件->解释器->程序: JDK:Java Development Kit,Java开发工具包: ...
- 解决clover配置文件conf.plist中nv_disable=1或者nvda_drv=1不生效或者说不能删除的问题
情况一:U盘安装MacOS的时候conf.plist中设置了nv_disable=1,但是启动的时候任然显示nvda_drv=1. 这种情况一般出现在该机器曾经安装过MacOS,MacOS会将这个参数 ...
- C# 8.0 中开启默认接口实现
原文:C# 8.0 中开启默认接口实现 当你升级到 C# 8.0 和 .NET Core 3.0 之后,你就可以开始使用默认接口实现的功能了. 从现在开始,你可以在接口里面添加一些默认实现的成员,避免 ...
- Fluentdata详解
Fluentdata 轻型orm 仅仅一个cs文件 创建并且初始化一个IDbContext. 二选一 public IDbContext Context() { return new DbContex ...
- 两个integer比较时为什么有时候会失效?
当数值不在 -128~127范围时就不会进行缓存操作,它会选择进行new integer()的操作.这样他们被分配到堆里面.[这个可以去查看integer.valueof()的源码].在用==或者!= ...