我正在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
声明变为internal
。public
类的成员经历了名称修改,使得从Java中意外使用它们变得更加困难,并允许根据Kotlin规则对具有相同签名的成员进行重载;
有没有办法解决这个问题?
答案 0 :(得分:3)
我看到你的所有internal classes都是关于encrypt& decrypt。
您可以通过定义顶级功能并将其标记为@JvmSynthetic
来轻松完成,然后将ECryptSymmetricDecrypt和ECryptSymmetricEncrypt类设为私有防止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 在init
块here中创建实例并计算结果是一件坏事。
AND 您可以使用Factory Method Pattern来避免在ECryptSymmetricDecrypt和ECryptSymmetricEncrypt类中进行类型检查。
答案 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
}
}