什么时候必须在 Java 中使用默认构造函数和参数化构造函数?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12798416/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 10:15:52  来源:igfitidea点击:

When is mandatory to have a default constructor along with parameterized constructor in Java?

javaconstructor

提问by Nihal Sharma

Many a time I have got an exception saying "the default constructor's implementation is missing". And many a times a parameterized constructor's definition alone does everything. I want to know under which conditions this happens.

很多时候我都会遇到一个异常,说“缺少默认构造函数的实现”。很多时候,参数化构造函数的定义本身就可以完成所有工作。我想知道在什么条件下会发生这种情况。

回答by Joachim Sauer

The compiler doesn't ever enforce the existence of a default constructor. You can have any kind of constructor as you wish.

编译器永远不会强制存在默认构造函数。您可以根据需要拥有任何类型的构造函数。

For some librariesor frameworksit might be necessary for a class to have a default constructor, but that is not enforced by the compiler.

对于某些框架,类可能需要具有默认构造函数,但这不是由编译器强制执行的。

The problem you might be seeing is if you have a class with a custom constructor and you don't have an implicit super()call in your constructor body. In that case the compiler will introduce a call to the super classes default constructor. If the super class doesn't have a default constructor then your classwill fail to compile.

您可能会遇到的问题是,如果您有一个带有自定义构造函数的类,并且您super()的构造函数主体中没有隐式调用。在这种情况下,编译器将引入对超类默认构造函数的调用。如果超类没有默认构造函数,那么您的类将无法编译。

public class MyClass extends ClassWithNoDefaultConstructor
    public MyClass() {
        super(); //this call will be added by the compiler if you don't have any super call here
        // if the super class has no default constructor the above line will not compile
        // and removing it won't help either because the compiler will add that call
    }
}

回答by Rohini Kumar

AS Joachim Sauersaid, its important/some times required to provide default constructor apart from your parametrized constructor when you are using frameworks like spring. Because if you want inject your class object through dependency injection in another class, then the class should have default constructor.

正如Joachim Sauer所说,当您使用 spring 等框架时,除了参数化构造函数之外,还需要提供默认构造函数很重要/有时需要。因为如果你想在另一个类中通过依赖注入来注入你的类对象,那么这个类应该有默认的构造函数。

Otherwise your dependency injection will fail.

否则你的依赖注入将会失败。

Its just one scenario where i encountered the importance of default constructor

这只是我遇到默认构造函数重要性的一种情况

回答by Stephen C

It is not entirely clear whether you are talking about a runtime exception or a compilation error.

您是在谈论运行时异常还是编译错误并不完全清楚。

A runtime exception will only occur if your code (or some library code called by your code) attempts to use reflection to create an instance of some class, and accidentally tries to use a non-existent constructor. (And I doubt that the exception message would use the term "default constructor" ...)

仅当您的代码(或由您的代码调用的某些库代码)尝试使用反射来创建某个类的实例,并且意外地尝试使用不存在的构造函数时,才会发生运行时异常。(而且我怀疑异常消息会使用术语“默认构造函数”......)

A compilation error happens because you are explicitly or implicitly attempting to call a "no args" constructor that does not exist. There are three scenarios'

发生编译错误是因为您显式或隐式地尝试调用不存在的“无参数”构造函数。一共有三种场景'

// case #1
new Foo();

// case #2
public Bar extends Foo {
  public Bar() {
    super();
  }
}

// case #3
public Bar extends Foo {
  public Bar() {
    // no explicit 'this' or 'super' call.
  }
}

The first two examples are pretty obviously invoking a no-args constructor.

前两个示例显然是在调用无参数构造函数。

The last example invokes the no-args constructor because if you don't have an explicit superor this"call" at the start of a constructor, the JLS says that a call to super()will occur ... in all cases apart from the constructor for Object.

最后一个示例调用无参数构造函数,因为如果在构造函数的开头没有显式superthis“调用”,则 JLS 表示将调用super()...... 在所有情况下,除了 for 的构造函数之外Object



Finally, you answer the question in the title:

最后,你回答标题中的问题:

When is mandatory to have a default constructor along with parameterized constructor in Java?

什么时候必须在 Java 中使用默认构造函数和参数化构造函数?

Strictly speaking, it is never mandatory to have a defaultconstructor. It is mandatory to have a no argsconstructor (either explicitly declared, or default) ... only if it is explicitly or implicitly called.

严格来说,拥有默认构造函数从来都不是强制性的。必须有一个no args构造函数(显式声明或默认)……仅当它被显式或隐式调用时。

(There could be libraries / frameworks that assumethat your classes have no-args constructors, but that is beyond the scope of what we can answer. And besides, such an assumption will be so that instances can be created reflectively ... and I've covered that.)

(可能有一些库/框架假设您的类具有无参数构造函数,但这超出了我们可以回答的范围。此外,这样的假设将使实例可以反射性地创建......而我已经涵盖了。)

回答by Parth Chauhan

  • case 1:
    If you don't write a constructor then default constructor will be added (by compiler) and you can create object using it. But if you write a parameterised constructor, and want to create object like

    ClassName ObjName = new ClassName();

    then you have to add default constructor manually.

  • case 2(Inheritances): If your childclass constructor do not make a
    explicit call to parentclass constructor (in first line itself), then compiler will do it for you.

    class ChildClass extends ParentClass{ ChildClass(){ //super() added by compiler. } }

    Now same thing,

    if no constructor in parentclass, fine Default Constructor (added by compiler) will be called.

    but if parentclass has a parameterised constructor, then there is no default constructor and so you get your error.

  • Its mandatory when you have a Parameterised constructor and

    1. want to create object like case 1.

    2. inherit this class and do not make a explicit call

      super(parameter,...);

      in first line of ChildClass constructor.

  • 情况 1:
    如果您不编写构造函数,则将添加默认构造函数(由编译器),您可以使用它创建对象。但是如果你写了一个参数化的构造函数,并且想要创建像

    ClassName ObjName = new ClassName();

    那么你必须手动添加默认构造函数。

  • 情况 2(继承):如果您的子类构造函数没有
    显式调用父类构造函数(在第一行本身),那么编译器将为您完成。

    class ChildClass extends ParentClass{ ChildClass(){ //super() added by compiler. } }

    现在同样的事情,

    如果父类中没有构造函数,则将调用精细的默认构造函数(由编译器添加)。

    但是如果父类有一个参数化的构造函数,那么就没有默认的构造函数,所以你会得到你的错误。

  • 当你有一个参数化的构造函数和

    1. 想要创建像案例 1 一样的对象。

    2. 继承这个类并且不进行显式调用

      super(parameter,...);

      在 ChildClass 构造函数的第一行。

回答by Sergey Gazaryan

In general this situation can be happen when instance of class is creating by reflection (for example while de-serializing). If your class is Serializable or instance of it can be created by reflection mechanism, you should define default constructor.

通常,当类的实例通过反射创建时(例如反序列化时),可能会发生这种情况。如果你的类是可序列化的或者它的实例可以通过反射机制创建,你应该定义默认构造函数。

回答by Jayesh

If there is no Constructor present in a class, one Default Constructor is added at Compile time.

如果类中不存在构造函数,则在编译时添加一个默认构造函数。

If there is any one parametrized Constructor present in a class, Default Constructor will not be added at Compile time.

如果类中存在任何一个参数化构造函数,则在编译时不会添加默认构造函数。

So if your program has any constructor containing parameters and no default constructor is specified then you will not be able to create object of that class using Default constructor.

因此,如果您的程序具有任何包含参数的构造函数并且未指定默认构造函数,那么您将无法使用默认构造函数创建该类的对象。

Eg:

例如:

class A{

A(int a){}

}

A a = new A() -----> Error.

-------------------------------------------------------

class A{

A(int a){}

A(){}

}

A a = new A() -----> It will work.

-----------------------------------------------------------

class A{

}

A a = new A() -----> It will work.

回答by Akki

Compiler will add default constructor when code is compiled but when you declared a parameterized constructor in code, default constructor will be omitted.

编译器会在编译代码时添加默认构造函数,但是当您在代码中声明参数化构造函数时,将省略默认构造函数。

When default constructor is overloaded with parameterized constructor, It is necessary to have a default constructor in code when you create object using default constructor instead of parameterized constructor.

当默认构造函数被参数化构造函数重载时,当您使用默认构造函数而不是参数化构造函数创建对象时,代码中必须有一个默认构造函数。

回答by Nikhil

There is a need of default constructor when you are using a framework (example: Spring framework) where you need to create instances of Spring bean and the bean class has only the parameterized constructor.

当您使用框架(例如:Spring 框架)需要创建 Spring bean 的实例并且 bean 类只有参数化构造函数时,需要默认构造函数。

@Component
public class Bank {
    private String bankName;
    public Bank(String bankName){
        this.bankName = bankName;
    }
    @Override
    public String toString() {
    return this.bankName;
   }
}

public class Test {
    public static void main(String[] args) {
        ApplicationContext context = new 
AnnotationConfigApplicationContext(SpringConfig.class);
        Bank bank = context.getBean(Bank.class);    
        System.out.println(bank);
    }
} 

will throw an error asking to implement default constructor

会抛出一个错误,要求实现默认构造函数