前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >正确地使用 Kotlin 的 internal

正确地使用 Kotlin 的 internal

作者头像
bennyhuo
发布2020-02-20 13:15:14
2.8K0
发布2020-02-20 13:15:14
举报
文章被收录于专栏:BennyhuoBennyhuo

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


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

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

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

代码语言:javascript
复制
internal fun zython() {
}

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

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

方法一

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

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

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

代码语言:javascript
复制
@JvmName(" zython")
internal fun zython() {
}

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

代码语言:javascript
复制
@JvmName("{-# LANGUAGE Zython #-}")
internal fun zython() {
}

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

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

方法二

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

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

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

代码语言:javascript
复制
internal fun ` zython`() {
}

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

代码语言:javascript
复制
internal fun `{-# LANGUAGE Zython #-}`() {
}

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

结束

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

我说完了。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2017-11-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Kotlin 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 方法一
  • 方法二
  • 结束
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档