使用Kotlin属性访问语法设置Java字段是否安全?

时间:2018-07-24 12:52:54

标签: java kotlin

这是一个假设的问题。 情况如下: 我正在从Kotlin文件中调用Java类的setter来更改私有字段df = df.pivot_table(index='Test_Category',columns='Test_Result', aggfunc='size')

的值
x

IDE建议将其更改为

javaFoo.setX(420)

它正常工作。

现在,假设设置器内部具有一些复杂的功能,随后在Java类的javaFoo.x = 420 字段中将其更改为x而不是public。不会有编译错误,但Kotlin调用将更改private的值,从而跳过设置程序中发生的其他事件,并且可能会被忽略而导致逻辑错误。因此,我想知道:使用Kotlin属性访问语法设置Java字段安全吗?

1 个答案:

答案 0 :(得分:2)

您对语言语义的分析是正确的。您描述的目标类的更改确实会更改Kotlin属性访问语法的语义。但是,在回答您的问题时并不是唯一要考虑的事实,该问题询问使用该语法是否是 safe

在讨论不受任何现实生活约束的假设情景时,几乎所有事情都是可能的,并且在这种观点下,没有任何语言结构是“安全的”。如果有一天,科特林团队决定将x++的语义更改为“返回x的平方,而不更改x”,该怎么办?从理论上讲,这是可能的。不过有可能吗?

将相同的常识逻辑应用于您的问题,这种情况是极不可能的,在这种情况下,类的维护者决定破坏迄今已隐藏在自定义器后面的字段的封装。实际上,如果您对所有Java库项目进行历史分析,那么您可能永远找不到一个实例。


也就是说,您的假设场景可能会被看作是对快捷语法实际问题的干扰。用它来调用带有自定义逻辑的二传手可能很尴尬,而且会产生误导,因为它破坏了我们的直觉。

在Android上,一个这样的示例是ImageView.get/setImageMatrix。你可以写

imageMatrix.rotate = 30

并希望这样做会起作用,但是实际上,您编写的代码已损坏。您实际上应该已经写过

val tmpMatrix = Matrix()
tmpMatrix.set(imageMatrix)
tmpMatrix.rotate = 30
imageMatrix = tmpMatrix

根据我们的Java直觉,实际上是这个版本看起来很破损,浪费了对象分配,似乎没有任何目的。但是,如果您阅读setImageMatrix的协定,您将意识到它所做的不仅仅是将对象分配给字段,它实际上将转换应用于图像视图。同样,getter的协定不允许对返回的对象进行变异。


关于Kotlin的此功能,我没有看到太多争论,但我认为它是从Java迁移的人们潜在的bug来源。解决方法是重新训练自己的直觉,让自己意识到以下事实:在Kotlin中进行任何财产访问都可能意味着更多。