java 为什么也可以使用空白构造函数?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/402514/
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
Why might one also use a blank constructor?
提问by Ziggy
I was reading some Java recently and came across something (an idiom?) new to me: in the program, classes with multiple constructors would also always include a blank constructor. For example:
我最近正在阅读一些 Java 并且遇到了一些新的东西(一个习语?):在程序中,具有多个构造函数的类也总是包含一个空白的构造函数。例如:
public class Genotype {
private boolean bits[];
private int rating;
private int length;
private Random random;
public Genotype() { // <= THIS is the bandit, this one right here
random = new Random();
}
/* creates a Random genetoype */
public Genotype(int length, Random r) {
random = r;
this.length = length;
bits = new boolean[length];
for(int i=0;i<length;i++) {
bits[i] =random.nextBoolean();
}
}
/* copy constructor */
public Genotype(Genotype g,Random r) {
random = r;
bits = new boolean[g.length];
rating = g.rating;
length = g.length;
for(int i=0;i<length;i++) {
bits[i] = g.bits[i];
}
}
}
The first constructor doesn't seem to be a "real" constructor, it seems as though in every case one of the other constructors will be used. So why is that constructor defined at all?
第一个构造函数似乎不是“真正的”构造函数,似乎在每种情况下都会使用其他构造函数之一。那么为什么要定义那个构造函数呢?
回答by Uri
I am not sure that the code you were reading was high quality (I've reviewed some bioinformatics code in the past and it is unfortunately often not written by professional developers). For example, that third constructor is not a copy constructor and generally there are problems in this code, so I wouldn't "read too much into it".
我不确定您正在阅读的代码是否高质量(我过去曾查看过一些生物信息学代码,但不幸的是,这些代码通常不是由专业开发人员编写的)。例如,第三个构造函数不是复制构造函数,并且这段代码通常存在问题,所以我不会“读太多”。
The first constructor is a default constructor. It only initializes the bare minimum and lets users set the rest with getters and setters. Other constructors are often "convenience constructors" that help create objects with less calls. However, this can often lead to inconsistencies between constructors. In fact, there is recent research that shows that a default constructor with subsequent calls to setters is preferable.
第一个构造函数是默认构造函数。它只初始化最低限度,并让用户使用 getter 和 setter 设置其余部分。其他构造函数通常是“方便的构造函数”,有助于以较少的调用创建对象。但是,这通常会导致构造函数之间的不一致。事实上,最近的研究表明,一个带有后续调用 setter 的默认构造函数是更可取的。
There are also certain cases where a default constructor is critical. For example, certain frameworks like digester (used to create objects directly from XML) use default constructors. JavaBeans in general use default constructors, etc.
在某些情况下,默认构造函数至关重要。例如,某些框架如摘要器(用于直接从 XML 创建对象)使用默认构造函数。JavaBeans 通常使用默认构造函数等。
Also, some classes inherit from other classes. you may see a default constructor when the initialization of the parent object is "good enough".
此外,一些类从其他类继承。当父对象的初始化“足够好”时,您可能会看到默认构造函数。
In this specific case, if that constructor was not defined, one would have to know all the details in advance. That is not always preferable.
在这种特定情况下,如果未定义该构造函数,则必须提前了解所有详细信息。这并不总是可取的。
And finally, some IDEs automatically generate a default constructor, it is possible that whoever wrote the class was afraid to eliminate it.
最后,有些 IDE 会自动生成默认构造函数,可能是编写该类的人都害怕消除它。
回答by Chris Nava
Is the object Serializable?
对象是否可序列化?
To allow subtypes of non-serializable classes to be serialized, the subtype may assume responsibility for saving and restoring the state of the supertype's public, protected, and (if accessible) package fields. The subtype may assume this responsibility only if the class it extends has an accessible no-arg constructor to initialize the class's state. It is an error to declare a class Serializable if this is not the case. The error will be detected at runtime.
During deserialization, the fields of non-serializable classes will be initialized using the public or protected no-arg constructor of the class. A no-arg constructor must be accessible to the subclass that is serializable. The fields of serializable subclasses will be restored from the stream
为了允许不可序列化的类的子类型被序列化,子类型可能负责保存和恢复超类型的公共、受保护和(如果可访问)包字段的状态。仅当它扩展的类具有可访问的无参数构造函数来初始化类的状态时,子类型才可能承担此责任。如果不是这种情况,则声明类 Serializable 是错误的。该错误将在运行时被检测到。
在反序列化期间,不可序列化类的字段将使用类的公共或受保护的无参数构造函数进行初始化。可序列化的子类必须可以访问无参数构造函数。可序列化子类的字段将从流中恢复
回答by amit
Yes, I agree the "blank" constructor should not always exist (in my experience beginners often make this mistake), although there are cases when blank constructor would suffice. However if the blank constructor violates the invariant that all the members are properly instantiated after construction, blank constructor should not be used. If the constructor is complicated, it is better to divide the construction into several protected/private methods. Then use a staticmethod or another Factoryclass to call the protected methods for construction, as needed.
是的,我同意“空白”构造函数不应该总是存在(根据我的经验,初学者经常犯这个错误),尽管在某些情况下空白构造函数就足够了。但是,如果空白构造函数违反了所有成员在构造后正确实例化的不变量,则不应使用空白构造函数。如果构造函数很复杂,最好将构造分成几个受保护/私有的方法。然后根据需要使用静态方法或另一个工厂类调用受保护的方法进行构造。
What I wrote above is the ideal scenario. However, frameworks like spring remove the constructor logic out of the code and into some xml configuration files. You may have getter and setter functions, but probably may be avoided from the interface, as described here.
我上面写的是理想的场景。但是,像 spring 这样的框架将构造函数逻辑从代码中移除并放入一些 xml 配置文件中。您可能有 getter 和 setter 函数,但可能可以从接口中避免,如here所述。
回答by gedevan
Default constructor is NOT mandatory.
默认构造函数不是强制性的。
If no constructors defined in the class then default (empty) constructor will be created automatically. If you've provided any parametrized constructor(s) then default constructor will not be created automatically and it's better to create it by yourself. Frameworks that use dependency injection and dynamic proxy creation at runtime usually require default constructor. So, it depends on use cases of class that you write.
如果类中没有定义构造函数,则将自动创建默认(空)构造函数。如果您提供了任何参数化构造函数,则不会自动创建默认构造函数,最好自己创建。在运行时使用依赖注入和动态代理创建的框架通常需要默认构造函数。因此,这取决于您编写的类的用例。
回答by alepuzio
The default constructor is'nt a good pratice for the functional view. The default constructor is used if the object have a global visibility into a method: for example, you want log the actual state of a object in a try/catch you can code
默认构造函数对于功能视图来说不是一个好的实践。如果对象对方法具有全局可见性,则使用默认构造函数:例如,您想在 try/catch 中记录对象的实际状态,您可以编码
MyObejct myObject=null
try{...
}catch(Exception e){
log.error(myObject);//maybe print null. information?
}
or do you prefer
或者你更喜欢
MyObejct myObject=new Object();
try{...
}catch(Exception e){
log.error(myObject);//sure print myobject.toString, never null. More information
}
?
?
Anotherway the create a EMPTY object have'nt a lot of logic, but instatiate a NULL object is harmuful in my opinion. You can read this post
另一方面,创建一个 EMPTY 对象没有很多逻辑,但在我看来,创建一个 NULL 对象是有害的。你可以阅读这篇文章
回答by Eldelshell
That is NOT a copy constructor. Basically you want empty constructors when working with some framework. Shall there always be an empty constructor, of course, public or private, but at least it allows you to keep control of how the class is being (or not) instantiated.
那不是复制构造函数。基本上,在使用某些框架时,您需要空的构造函数。是否总是有一个空的构造函数,当然,公共的或私有的,但至少它允许您控制类是(或不)实例化的方式。
回答by duffymo
I usually write one constructor that fully initializes the object; if there are others, they all call this(...) with appropriate defaults.
我通常会编写一个完全初始化对象的构造函数;如果还有其他人,他们都会用适当的默认值调用 this(...) 。
An object should be 100% initialized and ready for use when it's created.
对象应该 100% 初始化并在创建时准备好使用。
Some frameworks, for example Hibernate, demand a no-arg constructor. The way they clash with best practices makes me uneasy sometimes.
一些框架,例如 Hibernate,需要一个无参数的构造函数。它们与最佳实践发生冲突的方式有时让我感到不安。
回答by Mark Renouf
Having a default and empty (blank) constructor prevents you from having any final fields. This leads to a lot of mutability where there it is often not needed.
具有默认和空(空白)构造函数可防止您拥有任何最终字段。这导致了很多通常不需要的可变性。
The builder pattern allows you to mix these two styles and allow more flexible initialization while still having immutability by hiding a many-arg constructor behind the factory.
构建器模式允许您混合这两种样式并允许更灵活的初始化,同时通过在工厂后面隐藏多参数构造函数来保持不变性。
回答by Weidian Huang
For some POJO classes or simple class, default constructor is useful when you sometimes want to do unit testing on the class using them. You don't need to mock them, you can new an object with default constructor and test the value set and get from them or pass them as an argument.
对于某些 POJO 类或简单类,当您有时想对使用它们的类进行单元测试时,默认构造函数很有用。您不需要模拟它们,您可以使用默认构造函数新建一个对象并测试值集并从中获取或将它们作为参数传递。
回答by bwet
You want to create a blank constructor for the classes that extended this class and since it has been extended the class... the child now has super which references the class above it it's parent. In the event the child did not specify super(stuff)... the stuff inside to reference the other constructors to use it will now attempt to reference the empty constructor.
你想为扩展这个类的类创建一个空白的构造函数,并且因为它已经扩展了这个类......孩子现在有 super ,它引用它上面的类,它是它的父类。如果孩子没有指定 super(stuff) ......里面的东西引用其他构造函数来使用它现在将尝试引用空构造函数。
I'm not sure what the error will be I am coding my first parent object relationship now and was looking up things here ha cheers.
我不确定错误会是什么我现在正在编写我的第一个父对象关系并且正在这里查找东西哈哈欢呼。
I guess I should add the moment you make a constructor that isn't the empty one you lose the default empty one so now super() which is default in the extended class won't have something to point to. Of course if you created the extended classes to take care of super by specifying on which gets rid of the default super() then you sidestep this but what if someone wants to use your class and extend from it and didn't realize there isn't an empty set when you could have just created one.
我想我应该在你创建一个不是空的构造函数的那一刻添加你失去默认的空的构造函数,所以现在扩展类中的默认 super() 将没有任何指向。当然,如果您创建扩展类来处理 super 通过指定哪个摆脱默认的 super() 那么您就回避了这一点,但是如果有人想使用您的类并从中扩展并且没有意识到没有'当您可以创建一个空集时,它是一个空集。
This is my first post but wanted to take a crack from how I understand it.
这是我的第一篇文章,但想从我对它的理解中解脱出来。

