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

时间:2014-04-23 15:30:57

标签: 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
}

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

2 个答案:

答案 0 :(得分:3)

Groovy无法识别私有访问修饰符。 See this question. Groovy中没有任何私密内容。

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

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

Groovy依赖于设置'suppressAccessChecks'权限才能运行。 groovy.policy file for the core-groovy project有此通知:

/* 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)
 */

page on Groovy's website of "things you can do but better leave undone",它列出了隐私问题:

  
      
  1. 忽视其他对象的隐私
  2.         

    访问其他类的方法,字段或属性时,请执行   确保您不会干扰私人或受保护的成员。   目前Groovy没有正确区分公共,私人,   和受保护的成员,所以要小心自己。

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

答案 1 :(得分:2)

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

示例:

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

如果您确实想要解决编译器的限制,可以使用反射。我对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();