如何防止使用默认构造函数?

时间:2015-07-18 18:28:01

标签: groovy constructor instantiation default-constructor

我在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 constructorno-arg constructorno-args constructorno-arguments constructor

虽然这是一个远程相关的:

  

Named argument constructor
  如果没有声明构造函数,则可以创建对象[...]

据我所知,位置构造函数是声明的和Java类似的,如果没有明确的位置,你可以使用命名构造函数。我有一个想法,上面的默认构造函数调用(在testDynamic()中)实际上正在工作,因为它正在调用带有空映射的命名构造函数,但是由于命名构造函数部分以“如果没有构造函数”开头,我将其快速排除被宣布为“,我显然有一个。

1 个答案:

答案 0 :(得分:5)

在Groovy中,您可以调用不带参数的单个参数方法。 Null将在那时使用。 (除非参数具有基本类型,否则调用失败)。所以对于Groovy来说,为构造函数执行此操作也是完全合法的。计划在将来删除该功能。因此我们决定静态groovy编译器不会支持它。这就是静态编译器在这里编译失败的原因。因此,不会生成no-args构造函数,使用null值调用现有的String兼容值构造函数。如果您绝对想要阻止这种情况,可以尝试元编程来替换构造函数并添加空检查。 Groovy不会在这里为你抛出异常