【问题标题】:Why Default constructor need to declare in POJO file which has Parameterized Constructor while instantiating Object?为什么在实例化对象时需要在具有参数化构造函数的 POJO 文件中声明默认构造函数?
【发布时间】:2013-08-21 05:59:29
【问题描述】:

假设我有一个 POJO 类用户,其构造函数为 public User(int id, String name){...}。 但是当我实例化像User u=new User() 这样没有参数的User 对象时,Eclipse 会给出像构造函数User() 未定义 这样的错误。但是当我没有参数化构造函数时它工作正常。有人可以解释一下为什么它需要定义默认构造函数吗?

【问题讨论】:

    标签: java constructor pojo default-constructor


    【解决方案1】:

    仅当您未提供其他构造函数时才提供默认(无参数)构造函数。如果你甚至为你的类定义了一个构造函数,你必须使用显式定义的(即在你的代码中)构造函数之一来实例化对象。当然,您可以定义自己的零参数空构造函数,如果这适用于您正在尝试做的事情。

    编辑: why?的回复

    编译器提供了一个默认构造函数,以便在没有定义构造函数时可以实例化对象。但是,如果您定义了参数构造函数,则意味着当您创建该类的新实例时,它的变量应该使用您传递的参数进行初始化(或执行类似的操作)。如果没有这些初始化,对象可能不会以预期的方式运行。因此,编译器通过不定义默认构造函数(当您定义了一个)来防止此类事情发生。

    【讨论】:

    • 是的,我知道这个事实。但为什么会这样?为什么JVM每次都不提供默认构造函数?
    • 我对“为什么”没有很好的答案。因为这就是语言的构建方式。这可能是为了避免在调用没有明确定义的构造函数时造成混淆。 Java 为您提供默认构造函数是 100% 为您自己的方便提供的。
    • @VimalBera:提供默认构造函数的不是 JVM,而是 Java 编译器。
    • 不懂路的孩子需要牵手。但是知道去哪里的人不需要它。 如果没有定义构造函数,编译器会手握你。如果您有自定义构造函数,编译器会解释您不需要默认的无参数构造函数。如果需要,可以明确定义。
    • @VimalBera,它是这样的:编译器提供了一个默认构造函数,以便在没有定义构造函数时可以实例化对象。但是,如果您定义了参数构造函数,则意味着当您创建该类的新实例时,它的变量应该使用您传递的参数进行初始化(或执行类似的操作)。如果没有这些初始化,对象可能不会以预期的方式运行。因此,编译器通过不定义默认构造函数(当您定义了一个)来防止此类事情发生。
    【解决方案2】:

    如果开发者没有提供构造函数,编译器会自动添加无参数构造函数。但是,一旦您放置了自己的自定义参数化构造函数,编译器就会停止为您添加默认构造函数。

    在这种情况下,如果您仍想使用无参数构造函数,则必须自己显式提供:

    public User() {
    }
    
    public User(int id, String name) {
    }
    

    这背后的逻辑是:如果你定义了自己的参数化构造函数,你就是在声明构造函数中列出的参数是构造类的对象所必需的。因此,如果您的库的用户不提供这两个参数,您也可以隐式声明,该对象不应该能够构造。因此编译器不会为你添加无参数构造函数。

    如果您还想声明您的类在没有提供参数化构造函数中的指定参数并且您(没有 arg)的情况下仍然可以工作,那么您可以通过自己提供非 arg 构造函数来明确声明。

    【讨论】:

      【解决方案3】:

      我这么晚才给出答案,但让我们尝试与您分享我所知道的:

      1. 当你不提供构造函数时,编译器提供构造函数。为什么 ?因为它确定你将只用没有参数的构造函数来初始化你的对象。所以编译器会为你做这件事。

      2. 当您提供参数化构造函数时,编译器不知道您将使用哪个构造函数来初始化您的对象。所以编译器没有为你提供一个无参数的构造函数。所以你必须明确地写。

        希望对你有所帮助。

      【讨论】:

      • 感谢您分享您所拥有的。 :)
      【解决方案4】:

      编译器会自动为任何没有构造函数的类提供无参数的默认构造函数,但是如果您显式地为任何构造函数提供参数,则编译器将不会提供默认构造函数,主要是出于安全原因。

      所以你可以做的是

       public User(int id, String name){...}
       public User(){this(defualtID,defaultName)};
      

      【讨论】:

        【解决方案5】:

        Java 编译器自动为任何没有构造函数的类提供无参数的默认构造函数。如果您的类中没有定义构造函数,那么 Java 编译器将在您生成的类文件中添加一个无参数构造函数。但是如果你的类中有带参数的构造函数,那么你需要编写无参数的构造函数,编译器不会添加它。

        【讨论】:

        • 你一直在谈论 JVM 添加构造函数 - 它没有。编译器会。 (而且它是一个没有parameters,而不是arguments的构造器——参数是在调用构造器或方法时提供的。)
        • @JonSkeet 是的,我正在纠正它,而你正在评论 :-) 谢谢!
        • 但不是参数部分? (老实说,我不确定这个答案是否真的在 Kon 的基础上添加了任何内容。)
        • @JonSkeet,虽然我同意传递参数和接收参数的术语的一般用法;使用术语 默认无参数构造函数 很常见。
        • @RaviThapliyal:常见的,不正确的。为什么要传播这种不正确性?术语有很多不好的用法 - 我正在努力改进术语的使用,因为我认为它很重要。
        猜你喜欢
        • 2019-12-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-09-16
        • 2020-10-10
        • 2019-03-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多