我是在Java编译器的陪伴下长大的,Java编译器在类中没有显式构造函数时自动生成默认构造函数,而当我有任何显式构造函数时不生成。
据我所知,构造函数定义了必需的依赖关系,而属性定义了可选的依赖关系(最有可能使用缺省值...由构造函数设置)。如果您遵循上述规则(这是我在职业生涯中亲身体验到的),那么在面向对象的代码中,能够在<init>()
未定义的情况下调用<init>()
是完全错误的。
我尝试了一个简单的测试,注意到即使使用显式构造函数,也很容易在没有参数的情况下实例化对象。如何使此程序在编译时或运行时在标记为???
的行处失败?
class TestGroovy {
private final String name
TestGroovy(String name) {
this.name = name
}
static void main(String[] args) {
testStatic()
println()
testDynamic()
println()
testReflection()
}
@groovy.transform.CompileStatic
static void testStatic() {
println new TestGroovy("static");
println "compile error"
// Groovyc: [Static type checking] - Cannot find matching method TestGroovy#<init>().
// Please check if the declared type is right and if the method exists.
//println new TestGroovy(); // correct
}
static void testDynamic() {
println new TestGroovy("dynamic");
println new TestGroovy(); // ???
}
static void testReflection() {
println TestGroovy.class.newInstance([ "reflection" ] as Object[]);
println TestGroovy.class.newInstance(); // ???
}
@Override String toString() { return "Name: ${name}"; }
}
输出:
Name: static
compile error
Name: dynamic
Name: null
Name: reflection
Name: null
预期的:RuntimeException
而不是Name: null
。
我试图在Groovy documentation中找到相应的部分,但我没有找到任何真正相关的内容。我查找的关键字是default constructor
、no-arg constructor
、no-args constructor
、no-arguments constructor
。
尽管这里有一个远程相关的:
Named argument constructor 如果未声明任何构造函数,则可以创建对象[...]
据我所知,位置构造函数是声明的且类似于Java的构造函数,如果没有显式的位置构造函数,则可以使用命名构造函数。我认为上面的默认构造函数调用(在testDynamic()
中)实际上是有效的,因为它使用空映射调用命名构造函数,但我很快就排除了这一点,因为命名构造函数部分以"如果没有声明构造函数"开头,我显然有一个。
推荐答案
在Groovy中,您可以调用不带参数的单个参数方法。到时将使用NULL。(除非参数具有基元类型,否则调用将失败)。因此,Groovy对构造函数也这样做是完全合法且已定义的。该公司计划在未来移除这一功能。正因为如此,我们决定静态Groovy编译器永远不会支持它。这就是静态编译器在这里编译失败的原因。因此情况并非如此,在生成无参数的构造函数时,使用空值调用现有的字符串兼容值的构造函数。如果您绝对想要防止这种情况,您可以尝试元编程来替换构造函数,并添加一个空检查。Groovy不会在此为您引发异常
相关推荐
最新文章