仅使用来自 groovy 中另一个类的私有构造函数的类的实例化

The*_*ect 5 java groovy access-modifiers

我有如下场景,其中有一个World类只有一个私有构造函数和另一个类App

正如代码所示,一个新的实例World可以创建内部App类,尽管只有私有构造的World

在Java中是禁止的,我认为在groovy中也是禁止的,但是App运行没有任何错误。

// World.groovy
class World {
    private World() {
    }
}

// App.groovy
class App {
    static void main(String[] args) {
    def world = new World()
    println world
}
Run Code Online (Sandbox Code Playgroud)

我无法理解在 groovy 中怎么可能。另一个类如何在 groovy 中实例化一个只有私有构造函数的类?

Nat*_*hes 4

Groovy 无法识别私有访问修饰符。看到这个问题。Groovy 中没有任何私有内容。

至于 Groovy 如何做到这一点,Groovy 正在为您在 Groovy 中编写的内容生成类。它可以在类文件中写入它想要的任何访问修饰符。但您也可以使用 Groovy 来检查 Java 代码的私有部分。正如AlexR 的回答所示, Groovy 正在调用setAccessible构造函数。

安全管理员可以防止这种事情发生。在 groovysh 中,安全管理器是org.codehaus.groovy.tools.shell.util.NoExitSecurityManager,它仅在其父级非空时检查权限。在 groovysh 中,其父级为 null。

Groovy 依赖于设置“suppressAccessChecks”权限才能正常运行。core-groovy 项目的 groovy.policy 文件有这样的通知:

/* Notes on the contents of this policy file:
 *
 * The following methods in groovy have privileged operations wrapping
 * setAccessible.  If these wrappers are not provided, most codebases below
 * must have the following grant: 
 * permission java.lang.reflect.ReflectPermission "suppressAccessChecks";
 *  MetaMethod.createMetaMethod
 *  MetaMethod.invoke(Object Object[])
 *  ReflectionMetaMethod.invoke(Object Object[])
 *  DefaultGoovyMethods.dump(Object)
 */
Run Code Online (Sandbox Code Playgroud)

Groovy 的网站上有一个页面“你可以做但最好不要做”,这里列出了隐私问题:

  1. 忽视其他对象的隐私

访问其他类的方法、字段或属性时,请确保不会干扰私有或受保护的成员。目前,Groovy 无法正确区分公共成员、私有成员和受保护成员,因此请小心。

正如蒂姆·耶茨(Tim Yates)在相关问题上所说,目前尚不清楚这是缺陷还是功能。鉴于它可能会破坏现有代码,在我看来,它不太可能很快得到“修复”(如果有的话)。