Kotlin学习笔记(五)-kotlin与Java互操作,kotlin-kotlin
Kotlin学习笔记(五)-kotlin与Java互操作,kotlin-kotlin
kotlin与Java互操作
- kotlin与Java互操作
- 在Kotlin中调用Java
- 数组的互操作性
- 检查Java中的异常
- 调用Java的Object方法
- 关键字冲突
- Nothing类型
- 在Java中调用Kotlin
- 包级函数
- 访问Kotlin属性
- 调用实例字段
- 调用静态字段和方法
- Kotlin与Java的可见性
- 生成默认参数函数的重载
- 显示声明Kotlin中的异常
- Kotlin与Java简单实例对比
- 在Kotlin中调用Java
在Kotlin中调用Java
数组的互操作性
与java不同,Kotlin中数组是非型变得,即Kotlin不允许我们把一个Array赋值给一个Array。
// Kotlin
var arrayAny = arrayOf(1, "2", true)
val arrayString = arrayOf(1, 2, 3)
// arrayAny= arrayString // error, Type mismatch
// Java
String[] arrayString = new String[]{"1", "2", "3"};
Object[] arrayAny;
System.out.println(arrayAny = arrayString); //[Ljava.lang.String;@4dc63996
检查Java中的异常
Kotlin中,所有异常都是非受检的(Non-Checked Exception,编译器异常),这意味着编辑器不会强迫你捕获其中的任何一个,但是可能会有运行时异常,所以终归要处理。
// Java中JSONObject,编译期异常
JSONObject jsonObject = new JSONObject();
try {
jsonObject.put("key1", "key");
jsonObject.get("none_key")
jsonObject.get("none_key")
} catch (JSONException e) {
e.printStackTrace();
}
// Kotlin,并没有强制。
val jsonObject = JSONObject()
jsonObject.put("key1", "key")
// 此句运行时异常,如下log。
jsonObject.get("none_key")
01-31 16:26:29.923 18281-18281/com.autodesk.shejijia.consumer E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.autodesk.shejijia.consumer, PID: 18281
java.lang.RuntimeException: Unable to start activity
Caused by: org.json.JSONException: No value for none_key
at org.json.JSONObject.get(JSONObject.java:389)
at com.autodesk.shejijia.consumer.designer.project.activity.DesignerProjectActivity.initView(DesignerProjectActivity.kt:40)
at com.autodesk.shejijia.shared.framework.base.BaseActivity.onCreate(BaseActivity.java:46)
at android.app.Activity.performCreate(Activity.java:6910)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1123)
调用Java的Object方法
getClass() 获取对象的Java类。
val product = Product()
val simpleName = product.javaClass.simpleName
val simpleName1 = product::class.java.simpleName
println(simpleName) //Product
println(simpleName1) //Product
关键字冲突
一些Kotlin的关键字是Java中的有效标识符,比如in,object、is等,使用反引号(’)字符转义,一般IDE自动添加了。
Kotlin中调用:
fun main(args: Array<String>) {
JavaDemo.`is`()
}
Java中方法:
public static boolean is() {
return true;
}
Nothing类型
Kotlin的Nothing是一个特殊类型,在Java中没有对应的类型。在使用时Nothing参数的地方会生成一个原始类型。
Kotlin中:
fun emptyList(): List<Nothing> = listOf()
Java中:
List list = JavaKotlinKt.emptyList();
System.out.println(list); // []
在Java中调用Kotlin
包级函数
在package com.liuhe.kotlin内的JavaKotlin.kt源文件中声明了所有函数和属性,包括扩展函数,都将编译成一个名为
com.liuhe.kotlin.JavaKotlinKt的Java类中的静态方法。
访问Kotlin属性
class KotlinClass {
var id: Long = -1L
var name: String = "kotlin"
var isOpen: Boolean = true
var isBig: String = "Y"
@JvmField var no = 0
}
在Java中,一般字段会映射成set/get方法,以is开头的对应的规则(以isBig为例)是setXx,isXx。
调用实例字段
@JvmField注解对Kotlin属性字段标注,表示这是一个实例字段(Instance Field),Kotlin在编译时,不会给此字段生成Getters/Setters方法。
调用静态字段和方法
class KotlinClass {
companion object {
var innerId = "x001" // private
@JvmField
var innerName = "ABC" // public
fun getClassInnerId() = "x001"
@JvmStatic
fun getClassInnerName() = "ABC"
}
}
public class JavaDemo {
public static final void main(String[] args) {
String innerId = KotlinClass.Companion.getInnerId();
// String innerId = KotlinClass.getInnerId();// error
String innerName = KotlinClass.innerName;
// String innerName = KotlinClass.Companion.getInnerName(); // error
KotlinClass.getClassInnerName(); // ok
KotlinClass.Companion.getClassInnerName(); //ok
// KotlinClass.getClassInnerId(); //error
KotlinClass.Companion.getClassInnerId(); // 唯一的调用方式
}
}
Kotlin与Java的可见性
可见性修饰符
Kotlin | Java | 备注 |
---|---|---|
private | private | 它只会在声明它的文件内可见 |
protected | protected | |
internal | public | 它会在相同模块内随处可见 |
public | public | 默认修饰符,意味着你的声明将随处可见 |
一个模块是编译在一起的一套 Kotlin 文件,可以认为是一个module。
Java访问权限
Kotlin | 类内部 | 本包 | 子类 | 外部包 |
---|---|---|---|---|
public | v | v | v | v |
protected | v | v | v | x |
default | v | v | x | x |
private | v | x | x | x |
生成默认参数函数的重载
在kotlin中,一个函数中的参数如果设置了默认值,就可以重载调用,但是在Java中只能调用全参数的。如果在Java中也想重载调用,需要在Kotlin函数上加注解@JvmOverloads,这样编译器会针对此函数做特殊处理,生成多个重载函数。
Kotlin中:可以重载调用
fun f1(name: String = "name", age: Int = 10) {}
@JvmOverloads
fun f2(name: String = "name", age: Int = 10) {}
fun main(args: Array<String>) {
f1()
f1("xiaoming")
f1("xiaoming", 15)
}
Java中:未加@JvmOverloads, 只能调用全参数的
JavaKotlinKt.f1("xiaoming", 12);
// JavaKotlinKt.f1("xiaoming"); // error!!
JavaKotlinKt.f2("xiaoming");//ok
显示声明Kotlin中的异常
Kotlin中没有受检异常,比如下边定义的异常,虽然编译时未抛出异常,但是运行时候回抛异常。
object CheckKotlinException {
fun thisIsException() {
throw Exception("I am a Exception")
}
}
Java中调用:
public static final void main(String[] args) {
CheckKotlinException.INSTANCE.thisIsException();
}
Exception in thread "main" java.lang.Exception: I am a Exception
at CheckKotlinException.thisIsException(JavaKotlin.kt:39)
at JavaDemo.main(JavaDemo.java:23)
解决:使用注解@Throws(Exception::class),这样Java编译器就会检查此异常。
object CheckKotlinException {
@Throws(Exception::class)
fun thisIsException() {
throw Exception("I am a Exception")
}
}
Kotlin与Java简单实例对比
Java
for(String item : items)
for(Map.Entry<String,String> entry:map.entrySet())
Kotlin
for(item in items)
for((key,value) in map)
Java
HashMap<Integer, String> map = new HashMap<>();
map.put(1,"One");
map.put(2,"Two");
// Java7
for (String str : lists) {
System.out.println(str);
}
// Java 8+
list.forEach(aa -> System.out.println(aa));
Kotlin
val map = mapOf(1 to "One", 2 to "Two")
listOf.forEach { println(it) }
Java
void doSomething(int... numbers){
// 实现
}
Kotlin
fun doSomething(vararg numbers:Int){
// 实现
}
相关文章
- 暂无相关文章
用户点评