[英]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的网站上有一个页面“你可以做但最好不要做的事情” ,它列出了隐私问题:
- 忽视其他对象的隐私
访问其他类的方法,字段或属性时,请确保不要干扰私有或受保护的成员。 目前,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.