【问题标题】:How to prevent default constructor from being used?如何防止使用默认构造函数?
【发布时间】:2015-07-19 18:38:42
【问题描述】:

每当类中没有显式构造函数时,Java 编译器都会自动生成默认构造函数。当我有任何显式构造函数时不生成。

据我所知,构造函数定义了所需的依赖项,属性定义了可选的依赖项(很可能使用默认值......由构造函数设置)。如果您遵守上述规则(我在职业生涯中根据经验得出),那么在面向对象代码中能够调用<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 constructorno-arg constructorno-args constructorno-arguments constructor

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

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

据我了解,位置构造函数是已声明且类似于 Java 的构造函数,如果没有明确的位置构造函数,您可以使用命名构造函数。我有一个想法,上面的默认构造函数调用(在testDynamic() 中)实际上正在工作,因为它使用空映射调用命名构造函数,但我很快就排除了这一点,因为命名构造函数部分以“如果没有声明构造函数”开头",我显然有一个。

【问题讨论】:

    标签: groovy constructor instantiation default-constructor


    【解决方案1】:

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

    【讨论】:

    • 这实际上是有道理的,如果你知道的话。一个简单的assert name 完成了这项工作并证明调用了单参数构造函数。无论如何我都应该进行参数检查:)
    • 这是否记录在任何地方? (注意:我不考虑 this callout 文档,因为它与某处无关)。我猜它记录在Method selection algorithm
    • 我也想,它已经在某处提到过,但事实并非如此。我认为它在旧 codehaus 页面的一页上,但还不是新文档的一部分。但是是的,这将进入方法选择算法页面
    • 不幸的是,它仍未记录在案,并且“功能”仍然存在。我知道我的单参数构造函数被调用,但我不知道为什么。幸运的是,我终于想出了正确的搜索词组合来找到这个问题和答案,现在我可以继续我的生活了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-08-04
    • 1970-01-01
    • 1970-01-01
    • 2011-12-25
    • 2012-04-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多