我在Java编译器中长大,只要类中没有显式构造函数,就会自动生成默认构造函数;当我有任何明确的构造函数时,不会生成。
据我所知,构造函数定义了所需的依赖项,并且属性定义了可选的依赖项(很可能是默认值...由构造函数设置)。能够在未定义时调用<init>()
在面向对象的代码中是完全错误的,如果你遵守上述规则(我在职业生涯中凭经验选择)。
这是一个我尝试过的简单测试,并注意到即使使用显式构造函数,也可以很容易地实例化没有args的对象。 如何在标记为???
的行的编译时或运行时间使此程序失败?
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()
中)实际上正在工作,因为它正在调用带有空映射的命名构造函数,但是由于命名构造函数部分以“如果没有构造函数”开头,我将其快速排除被宣布为“,我显然有一个。
答案 0 :(得分:5)
在Groovy中,您可以调用不带参数的单个参数方法。 Null将在那时使用。 (除非参数具有基本类型,否则调用失败)。所以对于Groovy来说,为构造函数执行此操作也是完全合法的。计划在将来删除该功能。因此我们决定静态groovy编译器不会支持它。这就是静态编译器在这里编译失败的原因。因此,不会生成no-args构造函数,使用null值调用现有的String兼容值构造函数。如果您绝对想要阻止这种情况,可以尝试元编程来替换构造函数并添加空检查。 Groovy不会在这里为你抛出异常