kotlin汇总10-Java调用kotlin

4 篇文章 0 订阅

Java可以很容易的调用kotlin代码

1属性

比如kotlin有var firstName: String
其实等同于在Java中下面的定义

private String firstName;

public String getFirstName() {
    return firstName;
}

public void setFirstName(String firstName) {
    this.firstName = firstName;
}

2.Package-Level函数

kotlin代码

// example.kt
package demo

class Foo

fun bar() {
}

在Java调用如下

// Java
new demo.Foo();
demo.ExampleKt.bar();

可以通过@file:JvmName注释告诉Java,比如

//kotlin代码
@file:JvmName("DemoUtils")

package demo

class Foo

fun bar() {
}

//Java调用

// Java
new demo.Foo();
demo.DemoUtils.bar();

如果在同一自动生成的类(包名和类名一致)囊括了多个kotlin文件则需要使用@file:JvmMultifileClass,比如

// oldutils.kt
@file:JvmName("Utils")
@file:JvmMultifileClass

package demo

fun foo() {
}
// newutils.kt
@file:JvmName("Utils")
@file:JvmMultifileClass

package demo

fun bar() {
}

在Java中调用

// Java
demo.Utils.foo();
demo.Utils.bar();

3.对象实例的字段(fields)

可以通过@JvmField修饰,比如

//kotlin
class C(id: String) {
    @JvmField val ID = id
}
// Java
class JavaClient {
    public String getID(C c) {
        return c.ID;
    }
}

4.静态字段

4.1 使用@JvmField修饰
//kotlin
class Key(val value: Int) {
    companion object {
        @JvmField
        val COMPARATOR: Comparator<Key> = compareBy<Key> { it.value }
    }
}
// Java
Key.COMPARATOR.compare(key1, key2);
// public static final field in Key class
4.2使用lateinit修饰
//kotlin
object Singleton {
    lateinit var provider: Provider
}
// Java
Singleton.provider = new Provider();
// public static non-final field in Singleton class
4.3使用const修饰
//kotlin
// file example.kt

object Obj {
    const val CONST = 1
}

class C {
    companion object {
        const val VERSION = 9
    }
}

const val MAX = 239
//java
int c = Obj.CONST;
int d = ExampleKt.MAX;
int v = C.VERSION;

5.静态方法

通过@JvmStatic修饰

//kotlin
class C {
    companion object {
        @JvmStatic fun foo() {}
        fun bar() {}
    }
}
//java
C.foo(); // works fine
C.bar(); // error: not a static method
C.Companion.foo(); // instance method remains
C.Companion.bar(); // the only way it works
//kotlin
object Obj {
    @JvmStatic fun foo() {}
    fun bar() {}
}

//java
Obj.foo(); // works fine
Obj.bar(); // error
Obj.INSTANCE.bar(); // works, a call through the singleton instance
Obj.INSTANCE.foo(); // works too

6.可见域

  • kotlin的private成员函数变成java的private成员函数
  • kotlin的private顶级声明(直接在kotlin文件下面)变成java的包可见声明
  • kotlin的protected在Java还是一样,但是需要注意的是Java的protected可以访问同一个包下面的所有,但是kotlin是private+子类可见,所以明显Java的protected可见域比kotlin要大
  • kotlin的internal变成java的public
  • kotlin的public变成Java的public

7.KClass

有些时候需要从KClass类型中获取Kotlin方法,但是Class不等于KClass,所以你需要如下

kotlin.jvm.JvmClassMappingKt.getKotlinClass(MainView.class)

8.使用@JvmName处理签名冲突

比如下面

fun List<String>.filterValid(): List<String>
fun List<Int>.filterValid(): List<Int>

上面两个在Jvm的签名都是一样的:filterValid(Ljava/util/List;)Ljava/util/List;
所以需要区分,使用@JvmName

fun List<String>.filterValid(): List<String>

@JvmName("filterValidInt")
fun List<Int>.filterValid(): List<Int>

//在Java中调用
filterValid
filterValidInt

一个同样的例子

val x: Int
    @JvmName("getX_prop")
    get() = 15

fun getX() = 10

9.生成覆载方法

比如,有kotlin代码

fun f(a: String, b: Int = 0, c: String = "abc") {
    ...
}
//调用
f(a)
f(a, b)
f(a, b, c)

要想在Java也这样调用,所以对方法加上@JvmOverloads

@JvmOverloads fun f(a: String, b: Int = 0, c: String = "abc") {
    ...
}

// Java,自动生成的
void f(String a, int b, String c) { }
void f(String a, int b) { }
void f(String a) { }

10.检查异常

比如有kotlin代码

// example.kt
package demo

fun foo() {
    throw IOException()
}

//我们希望在java如下调用
// Java
try {
  demo.Example.foo();
}
catch (IOException e) { // error: foo() does not declare IOException in the throws list
  // ...
}

需要如下添加@Throws注释,如下

@Throws(IOException::class)
fun foo() {
    throw IOException()
}

11.Null安全

不保证

12.变体泛型

如下kotlin代码

class Box<out T>(val value: T)

interface Base
class Derived : Base

fun boxDerived(value: Derived): Box<Derived> = Box(value)
fun unboxBase(box: Box<Base>): Base = box.value

//可以天真的用下面的Java代码代替
Box<Derived> boxDerived(Derived value) { ... }
Base unboxBase(Box<Base> box) { ... }

//但是有个问题,
unboxBase(boxDerived("s")) 这行代码可以在kotlin没问题,因为Box<Derived>是Box<Base>的子类型(注意out修饰了泛型),但是在Java,我们知道肯定报错的。所以
Base unboxBase(Box<Base> box) { ... }//ERROR,要改成如下
Base unboxBase(Box<? extends Base> box) { ... } //这样就可以使用unboxBase(boxDerived("s"))

13.Nothing的转化

//kotlin
fun emptyList(): List<Nothing> = listOf()
// is translated to Java
List emptyList() { ... }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
根据提供的引用内容,出现了两个关于Kotlin的错误信息。第一个引用中显示了一个无法解析依赖的错误,指出无法下载kotlin-reflect.jar文件。第二个引用中显示了一个关于kotlin-gradle-1.8.10.jar (org.jetbrains.kotlin:kotlin-reflect)",这个错误通常是由于Gradle无法找到所需的kotlin-reflect库而引起的。解决这个问题的方法是确保你的项目的Gradle配置正确,并且指定了正确的Kotlin版本。 你可以尝试以下几个步骤来解决这个问题: 1. 确保你的项目的build.gradle文件中包含了正确的Kotlin版本和kotlin-gradle-plugin版本。你可以在build.gradle文件中找到类似于以下代码的部分: ```groovy ext { kotlin_version = '1.8.10' } dependencies { // ... implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" // ... } buildscript { // ... dependencies { // ... classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" // ... } } ``` 请确保kotlin_version变量的值与你想要使用的Kotlin版本一致,并且在dependencies和buildscript的classpath中正确引用了kotlin-gradle-plugin。 2. 如果你已经确认了build.gradle文件中的配置正确无误,那么可能是因为Gradle无法从远程仓库下载kotlin-reflect.jar文件。你可以尝试清除Gradle的缓存并重新构建项目。在命令行中执行以下命令: ```shell ./gradlew clean ``` 然后重新构建项目: ```shell ./gradlew build ``` 这将清除Gradle的缓存并重新下载所需的依赖。 3. 如果上述步骤***切换到其他网络环境来解决这个问题。 希望以上步骤能够帮助你解决问题。如果你还有其他问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值