我有一个方案,例如关注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中实例化一个只有私有构造函数的类?
答案 0 :(得分:3)
Groovy无法识别私有访问修饰符。 See this question. Groovy中没有任何私密内容。
至于Groovy是如何做到的,Groovy正在为你在Groovy中编写的东西生成类。它可以在类文件中编写它想要的任何访问修饰符。但是您也可以使用Groovy来检查Java代码的私有部分。 Groovy在构造函数上调用setAccessible
为AlexR'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",它列出了隐私问题:
- 忽视其他对象的隐私
醇>访问其他类的方法,字段或属性时,请执行 确保您不会干扰私人或受保护的成员。 目前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();