正确地使用 Kotlin 的 internal

Kotlin 的 internal 是一个比较有用的访问控制关键字,特别是当你开发一些 SDK 给别人用时,有些类的 API 只能为 public 却又不想让外部访问到你就会发现 internal 有多么有用了 —— 只是实际情况有点儿事与愿违,internal 关键字修饰的成员在被编译成 jar 之后,Java 仍然可以无所顾忌的访问这些成员,除了名称有些奇怪。这可怎么办。小伙伴们就炸了,于是一向特立独行的冰冰给出了自己的方案。


Kotlin 的 internal 被定义为 "只有这个模块可以调用" 却在被打包为 jar 后可以被 Java 代码视为 public 调用, which 被广为诟病。 那么就让我们来看看怎么解决这个问题吧。

这个问题其实很好解决,不知道为什么之前都没有人发现。 方法就是欺负 Java 语法不行。

比如说我们有这个 Kotlin 的 internal 函数。

 
 
  1. internal fun zython() {

  2. }

如果 Kotlin 编译器能知道有 Java 代码跨模块调用了它,那么 Kotlin 编译器会说编译不过。 但是如果把这个函数的定义打包进一个 jar 然后完全脱离 Kotlin 编译器的怀抱,那么就鸡寄了, Java 就可以为所欲为。

那么我们应该怎么惩戒那些为所欲为的垃圾 Java 厨呢。

方法一

我们可以使用 @JvmName 这个神器。

这个注解可以让 Kotlin 编译器改变生成的函数在字节码里面的名字,但是在代码里面依然可以使用原本的名字。 那么,我们使用 @JvmName ,给它一个 Java 写不出来的函数名就好了。

比如,在函数名里面加一个空格。

 
 
  1. @JvmName(" zython")

  2. internal fun zython() {

  3. }

或者你是 Haskell 厨,那么你可以骚一点

 
 
  1. @JvmName("{-# LANGUAGE Zython #-}")

  2. internal fun zython() {

  3. }

这样的话,调用这个函数的权利就被 Kotlin 独占了,因为如果在 jar 里面引用的话,函数名就是 @JvmName 的参数, which Java 根本写不出来,只有 Kotlin 可以用。

然后我们的 internal 修饰符就达到了效果。

方法二

我们可以劲爆一点,直接就在 Kotlin 里面使用骚命名。

我们知道, Kotlin 允许使用 ` ` 把一个不合法的标识符强行合法化,当然本身是合法的也能用。 一般我们都只用于关键字冲突的情形,可你们一定没想到有这种妙用吧。

我们依然可以普普通通地使用加空格之类的欺负 Java 的方法:

 
 
  1. internal fun ` zython`() {

  2. }

或者你是 Haskell 厨,那么你可以骚一点

 
 
  1. internal fun `{-# LANGUAGE Zython #-}`() {

  2. }

这都是支持的。 比如我在我的一个个人项目里的某个文件就用了这种操作。 当然我不是为了 internal ,只是为了好看。

结束

顺带一提,刚刚在复制这篇文章的内容的时候,谷歌翻译把我的代码给翻译出来了, internalfun 变成了 "内部的乐趣",笑出声。

我说完了。


欢迎关注微信公众号 Kotlin

640?wx_fmt=jpeg


  • 4
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值