【问题标题】:Hiding Kotlin object's INSTANCE field from Java (and Kotlin)从 Java(和 Kotlin)隐藏 Kotlin 对象的实例字段
【发布时间】:2019-05-21 11:51:12
【问题描述】:

小问题

我能否将 Kotlin 对象的 INSTANCE(用于 Java 互操作)的可见性修改为 internal 或更低?

长问题

我正在编写一个库,并且我想要一个 API 文件/类,用 Kotlin 编写,它公开了一个要从 Java 或 Kotlin 调用的函数,如下所示:

科特林:

API.function()

Java:

API.function();

我可以这样写:

科特林:

object API {
    @JvmStatic
    fun function() = TODO()
}

不过,现在我也可以这样做了:

Java:

API.INSTANCE.function();

为了简单起见,我想阻止对 INSTANCE 的这种访问,以将我的 API 表面保持在最低限度。

我可以将INSTANCE 的可见性修改为internal 或更低吗?

这可能是不可能的,因为对 API 的任何调用(来自 Kotlin)都会返回对象的实例,并且可能也应该隐藏它才能实现。但是,我很好奇它是否没有重大黑客攻击。

使用 Java 的解决方案是用 Java 编写 API

public final class API {
    private API() {
    }

    public static void function() {
    }
}

但是,我正在寻找用 Kotlin 编写的解决方案。

【问题讨论】:

  • 你考虑过用Java写接口,用Kotlin实现吗?
  • 我想你一开始就不想要object (~singleton)(也许你心里有一个Utilitity-class,因为这是在Java?;-)),而是一组可通过通用接口访问的函数...Linos 的答案向您展示了这一点,并且它将被包装成您在 Java 方面感到满意的内容...

标签: java kotlin singleton interop kotlin-java-interop


【解决方案1】:

我能想到的最接近的是这样的:

在包com.example.api 中创建一个文件API.kt。将您的函数直接添加到该文件中,如下所示:

@file:JvmName("API")

package com.example.api

fun function() {
    // ...
}

科特林:

您可以在需要使用 api 的任何地方导入该函数:

import com.example.api.function

虽然你不能再使用你的语法API.function

Java:

生成的类看起来像这样(没有单例,只有静态方法,但没有私有构造函数):

 public final class API {
     public static final void function() {
         // ...
     }
 }

然后允许您将其称为API.function();


通过指定@file:JvmName("API"),您指示kotlin 将创建的类命名为API

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-10
    • 2019-12-07
    相关资源
    最近更新 更多