Kotlin保护变量在不同模块但相同包的Java子类中不可用

4ngedf3f  于 7个月前  发布在  Kotlin
关注(0)|答案(1)|浏览(81)

我显然不理解Kotlin的继承规则。在Java中,任何受保护的变量都可以在变量所在类的任何子类中使用。在Kotlin中,这些规则似乎不适用。我得到了一个编译错误'logger' has private access in com.example.MainActivity
感兴趣的Kotlin代码:

package com.example.ui

abstract class MainActivity : Activity() {
    protected val logger = LoggerFactory.getLogger(this.javaClass)
    //... other classy stuff...
}

字符串
Java子类:

package com.example.ui;

public class MobileMainActivity extends MainActivity {
    @Override
    public void onCreate(Bundle savedInstanceState) { //superclass derives from Activity; this is fine
        //red squiggly, logger is not available, even though it's protected, in the same package, and inherits from MainActivity
        logger.info("Sending multicast message for configuration...");
    }
}


当我阅读文档时,Kotlin似乎和Java一样对待受保护的变量。
Kotlin文档:https:kotlinlang.org/docs/visibility-modifiers.html#class-members
我是否被迫使用getLogger()访问器而不是变量本身?这是否会使Java中的变量实际上是private而不是protected?为什么?根据文档,它不应该...在哪里可以找到有关使用Kotlin和Java构建混合语言项目时的差异的信息?看起来这可能会使迁移工作复杂化,但我认为它不可能是完美的。

ubbxdtey

ubbxdtey1#

我是否必须使用getLogger()访问器而不是变量本身?
不,您可以添加@JvmField来使Kotlin属性编译为Java中的字段。

@JvmField
protected val logger = ...

字符串
这在Java中为您提供了一个受保护的字段,并且getLogger方法将不再可用。
这不是使它在Java中实际上是私有的而不是受保护的吗?
getLogger是Java中受保护的方法。
当你使用两种语言时,你应该看看Kotlin-Java互操作文档,而不是关于Kotlin语言的一般文档。它非常清楚地说,当每个Kotlin属性有一个backing字段时,都会为它生成一个私有字段:
Kotlin属性被编译为以下Java元素:

  • 一个getter方法,其名称通过在前面加上get前缀来计算
  • 一个setter方法,其名称通过前缀set计算(仅适用于var属性)
  • 私有字段,与属性名称同名(仅适用于具有支持字段的属性)

相关问题