如何防止使用默认构造函数?
How to prevent default constructor from being used?
我是随着 Java 编译器在 class 中没有显式构造函数时自动生成默认构造函数而长大的;当我有任何显式构造函数时不生成。
据我所知,构造函数定义了必需的依赖项,属性定义了可选的依赖项(很可能使用默认值...由构造函数设置)。在未定义时能够调用 <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
If no constructor is declared, it is possible to create objects [...]
据我了解,位置构造函数是声明的并且类似于 Java 的构造函数,如果没有明确的位置 ,您可以使用命名构造函数 。我认为上面的默认构造函数调用(在 testDynamic()
中)实际上是有效的,因为它使用空映射调用命名构造函数,但我很快就排除了这一点,因为命名构造函数部分以 [=49= 开头],我明明有一个
在Groovy中,您可以调用不带参数的单参数方法。届时将使用 Null。 (除非参数具有原始类型,否则调用失败)。因此,为 Groovy 定义构造函数也是完全合法的。计划在未来删除该功能。因此我们决定静态 groovy 编译器将永远不支持它。这就是静态编译器在这里编译失败的原因。因此,生成无参数构造函数的情况并非如此,采用空值调用构造函数的现有 String 兼容值。如果你绝对想阻止这种情况,你可以尝试元编程来替换构造函数并添加空检查。 Groovy不会在这里为你抛出异常
我是随着 Java 编译器在 class 中没有显式构造函数时自动生成默认构造函数而长大的;当我有任何显式构造函数时不生成。
据我所知,构造函数定义了必需的依赖项,属性定义了可选的依赖项(很可能使用默认值...由构造函数设置)。在未定义时能够调用 <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
If no constructor is declared, it is possible to create objects [...]
据我了解,位置构造函数是声明的并且类似于 Java 的构造函数,如果没有明确的位置 ,您可以使用命名构造函数 。我认为上面的默认构造函数调用(在 testDynamic()
中)实际上是有效的,因为它使用空映射调用命名构造函数,但我很快就排除了这一点,因为命名构造函数部分以 [=49= 开头],我明明有一个
在Groovy中,您可以调用不带参数的单参数方法。届时将使用 Null。 (除非参数具有原始类型,否则调用失败)。因此,为 Groovy 定义构造函数也是完全合法的。计划在未来删除该功能。因此我们决定静态 groovy 编译器将永远不支持它。这就是静态编译器在这里编译失败的原因。因此,生成无参数构造函数的情况并非如此,采用空值调用构造函数的现有 String 兼容值。如果你绝对想阻止这种情况,你可以尝试元编程来替换构造函数并添加空检查。 Groovy不会在这里为你抛出异常