这是一个假设的问题。
情况如下:
我正在从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字段安全吗?
答案 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中进行任何财产访问都可能意味着更多。