繁体   English   中英

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

[英]Instantiation of a class with only private constructor from another class in groovy

我有一个场景,如下面的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
}

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

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

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

安全经理可以阻止这种事情。 在groovysh中,安全管理器是org.codehaus.groovy.tools.shell.util.NoExitSecurityManager ,它只检查其父项是否为org.codehaus.groovy.tools.shell.util.NoExitSecurityManager权限。 在groovysh中,它的父级为空。

Groovy依赖于设置'suppressAccessChecks'权限才能运行。 核心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)
 */

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

  1. 忽视其他对象的隐私

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

正如蒂姆耶茨在链接问题上所说,目前尚不清楚这是一个缺陷还是一个特征。 鉴于它可能会破坏现有的代码,我似乎不太可能在任何时候很快得到“修复”,如果有的话。

创建私有构造函数通常的目标是阻止从外部创建类的实例。 通常,如果类提供其他方法来创建其实例,例如静态工厂方法,则会执行此操作。

例子:

  • 可以使用Pattern.compile()创建java.util.Pattern
  • 单身设计模式

但是,如果您确实想要解决编译器的限制,可以使用反射。 我对Groovy不太熟悉,但这里是你如何在java中做到这一点。

Constructor c = World.class.getConstructor();
c.setAccessible(true); // This line grants you permission to access even private elements
World w = (World)c.newInstance();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM