Java中的Kotlin内部类可以公开显示

时间:2017-07-29 19:47:34

标签: java android class kotlin public

我正在Kotlin开发Android crypto library。我有几个test_ques ------------------------------ id | ques | skill_id 1 | xyz | 1 2 | xyz | 1 3 | xyz | 1 4 | xyz | 1 5 | xyz | 1 6 | xyz | 2 7 | xyz | 2 8 | xyz | 2 9 | xyz | 2 10 | xyz | 2 11 | xyz | 2 12 | xyz | 3 13 | xyz | 3 14 | xyz | 3 15 | xyz | 3 16 | xyz | 3 17 | xyz | 3 skills ------------ id | score 1 | 15 2 | 20 3 | 25 类在Java应用程序中公开可见。在文档中找到this

  Java中的

internal声明变为internalpublic类的成员经历了名称修改,使得从Java中意外使用它们变得更加困难,并允许根据Kotlin规则对具有相同签名的成员进行重载;

有没有办法解决这个问题?

4 个答案:

答案 0 :(得分:3)

我看到你的所有internal classes都是关于encrypt& decrypt

您可以通过定义顶级功能并将其标记为@JvmSynthetic来轻松完成,然后将ECryptSymmetricDecryptECryptSymmetricEncrypt类设为私有防止Java客户端访问您的内部类,例如:

// define this top-level function in your ECryptSymmetricEncrypt.kt

@JvmSynthetic internal fun <T> encrypt(
                                       input:T, password: String, cipher:Cihper, 
                                       erl: ECryptResultListener, outputFile:File,
                                       getKey:(String,ByteArray)->SecretKeySpec){

  ECryptSymmetricEncrypt(input, password, cipher,
                { pass, salt -> getKey(pass, salt) }, erl, outputFile)
}

然而,它解决了你的问题,但我仍然想说你的代码可以进一步分解成小块。例如,加密&amp;解密算法有很多重复,也许你可以在加密库中使用Template Method Pattern&amp;引入接口以显式创建库并在实现类下隐藏Cipher操作。理想情况下,客户端代码无法通过java.security.*Encrypt接口查看任何Decrypt类。例如:

interface Encrypt{
   //          v--- don't include the infrastructure class here,e.g:`Keys`,`Cipher`
   fun encode(...args)
}

interface Decrypt{
   //          v--- don't include the infrastructure class here,e.g:`Keys`,`Cipher`
   fun decode(...args)
}

AND inithere中创建实例并计算结果是一件坏事。

AND 您可以使用Factory Method Pattern来避免在ECryptSymmetricDecryptECryptSymmetricEncrypt类中进行类型检查。

答案 1 :(得分:2)

除了@JvmSynthetic之外,您可以将@JvmName与非法的Java标识符一起使用,例如添加空格。

例如,我在@JvmName param中添加了一个空格,因此除了Kotlin之外的任何语言都无法调用您的方法:

@JvmName(" example")
internal fun example() {
}

答案 2 :(得分:0)

根据我在another线程中对此问题的回答:

不是完美的解决方案,但我发现了两个hacky解决方案

internal class处用@JvmName注释该internal class LibClass { @JvmName(" ") // Blank Space will generate error in Java fun foo() {} @JvmName(" $#") // These characters will cause error in Java fun bar() {} } 的每个公共方法,用空格或特殊符号会在Java中生成语法错误。

例如

internal class

由于上述解决方案不适用于管理大型项目或似乎不是好的做法,因此以下解决方案可能会有所帮助。

@JvmSynthetic注释该internal class LibClass { @JvmSynthetic fun foo() {} @JvmSynthetic fun bar() {} } 的每个公共方法,而Java不能访问这些公共方法。

例如

{{1}}

注意:

此解决方案保护该函数的方法/字段。按照问题,它不会隐藏Java中类的可见性。因此,仍在等待完美的解决方案。

答案 3 :(得分:0)

利用包含方法的私有构造函数+伴随对象实例化用JvmSynthetic注释的保留封装。

// Private constructor to inhibit instantiation
internal class SomeInternalClass private constructor() {

    // Use the companion object for your JvmSynthetic method to
    // instantiate as it's not accessible from Java
    companion object {
        @JvmSynthetic
        fun instantiate(): SomeInternalClass =
            SomeInternalClass()
    }

    // This is accessible from Java
    @JvmSynthetic
    internal var someVariable1 = false

    // This is accessible from Java
    @JvmSynthetic
    var someVariable2 = false



    // This is inaccessible, both variable and methods.
    private var someVariable3 = false
    @JvmSynthetic
    fun getSomeVariable3(): Boolean =
        someVariable3
    @JvmSynthetic
    fun setSomeVariable3(boolean: Boolean) {
        someVariable3 = boolean
    }
}