You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

同包不同模块下Java子类无法访问Kotlin的protected变量问题

问题原因

你遇到的问题核心是Kotlin的protected可见性与Java的细微差异,以及Kotlin属性的默认封装行为:

  1. Kotlin中用protected修饰的属性,默认会生成一个private的底层字段,同时生成protected的getter方法(比如getLogger())。Java子类无法直接访问这个私有字段,只能通过getter方法访问。
  2. 另外,Kotlin的protected比Java更严格:它仅允许子类访问,同包非子类的类无法访问(不过你的情况是子类,所以主要是第一个原因)。
解决方案

有两种方式解决这个问题:

方案1:在Java子类中调用getter方法

直接使用Kotlin自动生成的protected getter方法访问:

@Override
public void onCreate(Bundle savedInstanceState) {
    getLogger().info("Sending multicast message for configuration...");
}

方案2:给Kotlin属性添加@JvmField注解

如果希望Java子类能像访问Java的protected字段一样直接用logger,可以给Kotlin的属性加上@JvmField注解,它会让Kotlin直接生成一个protected的公开字段,而不是私有字段+getter:

package com.example.ui

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

这样Java子类里直接写logger.info(...)就不会报错了。

补充说明
  • 你提到的“这在Java中不就相当于private了吗?”——其实不是,Kotlin的protected修饰的是属性的访问权限,只是默认的字段是private,但getter是protected的,和Java的protected成员的访问权限本质是一致的,只是封装方式不同。
  • 关于Kotlin与Java混合项目的差异,建议查看Kotlin官方文档中的Java互操作相关章节,里面详细说明了可见性修饰符、属性、方法等在两种语言间的行为差异,能帮你减少迁移中的坑。

内容的提问来源于stack exchange,提问作者moonlightcheese

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 08:55:06