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

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不会在这里为你抛出异常