Scala中使用getDeclaredFields无法访问私有字段?求助
Scala反射访问私有字段的问题解析
你的代码运行后无输出,核心原因是Scala编译器的优化机制擦除了未被使用的私有字段,而非反射无法访问私有字段。
问题根源
你定义的private val isBlack仅完成了赋值,但没有在任何代码中被引用。Scala默认开启的优化编译器会自动移除这类"无用"的私有字段,不会生成对应的Java字节码字段,导致getDeclaredFields找不到任何可遍历的字段,自然没有输出。
修复验证
给私有字段添加一个使用场景,比如新增方法引用它,编译器就会保留这个字段:
class Cat(isBlackC: Boolean){ private val isBlack: Boolean = isBlackC def getColorStatus(): Boolean = isBlack // 引用私有字段,避免被优化擦除 } val cat = new Cat(true) for(field <- cat.getClass.getDeclaredFields){ field.setAccessible(true) println(s"字段名: ${field.getName}, 字段值: ${field.get(cat)}") }
运行这段代码就能看到预期输出,比如:
字段名: isBlack, 字段值: true
关于Scala私有字段的反射访问
完全可以通过Java反射访问Scala的私有字段,只要字段未被编译器优化擦除,步骤和你写的一致:
- 调用
getDeclaredFields获取类中所有声明的字段(包含私有、保护级别的字段) - 调用
setAccessible(true)绕过访问权限检查 - 调用
get(obj)获取目标对象的字段值
额外提示
- 如果是
private[this] val(对象私有字段),反射依然可以正常访问,和普通private val无区别 - 若想保留未被使用的字段,可关闭编译优化,比如在编译时添加参数
-opt:l:none
内容的提问来源于stack exchange,提问作者lilith43
相关产品推荐
相关产品推荐

