Constructor overloading - best practice in Java
What is a better approach in case of consistency?
- Make all child constructors private.
Introduce static factory methods.
ListBubbleSort.withList(List<E> list)
ListBubbleSort.withComparator(Comparator<E> comparator)Make a call to a proper
super
constructor. Don't pass anynull
s.public static <E> ListBubbleSort withList(List<E> list) {
return new ListBubbleSort(list);
}
private ListBubbleSort(List<E>) {
super(list);
}
protected ListSortierer(List<E>) {
// initialise only the list field
this.origin = list;
}Don't use
Optional
as a field.this.original = Optional.ofNullable(li);
Consider the Builder Pattern if you have 3+ parameters.
Handle missing values in the abstract superclass or in the subclass?
A constructor is supposed to provide initial values.
You aren't passing initial values, you are just indicating their absence.
By default, null
is the initial value for reference types. So, there is no need to reassign a field if the value for it hasn't been given.
Does it make a difference regarding instantiation or is it just a matter of opinion?
Readability, maintenance.
I would recommend reading Effective Java by Joshua Bloch:
Creating and Destroying Objects
- Item 1: Consider static factory methods instead of constructors
- Item 2: Consider a builder when faced with many constructor parameters
Constructor overloading in Java - when to use it?
The short answer is: you should use overloading whenever you need it.
As a real-life example, take a look at the JLabel API: https://docs.oracle.com/javase/8/docs/api/javax/swing/JLabel.html
JLabel has quite a few constructors: one that just takes a String, one that takes a String and an icon, one that only takes an icon, and one that doesn't take any arguments at all.
You would use each constructor when you want to construct that kind of JLabel: one that displays a String, one that displays a String and an icon, one that only displays an icon, or one that doesn't display anything yet (until you call one of its setter functions).
Overloading constructor of a class and each constructor will have different instance variables
If you want your different constructors to setup instances with different sets of instance variables, then you want to create instances of different classes. Those can inherit a base class with the common parts.
(This, though very short, has been perceived as an answer by OP and @user. I create it to get the question out of the list of unanswered questions. Let me know when a more helpful or technically detailed answer is created. I don't mind deleting mine then.)
Is it correct to use multiple constructors this way?
For the code you posted, this would be a simple approach:
package com.steve.research;
public class Quiz {
private int counter;
private String question;
private String answer1;
private String answer2;
private String answer3;
private String answer4;
private String answer5;
private String answer6;
private String rightAnswer;
public Quiz(int counter, String question, String answer1, String answer2, String rightAnswer) {
this(counter, question, answer1, answer2, null, null, rightAnswer);
}
public Quiz(int counter, String question, String answer1, String answer2, String answer3, String rightAnswer) {
this(counter, question, answer1, answer2, answer3, null, rightAnswer);
}
public Quiz(int counter, String question, String answer1, String answer2, String answer3, String answer4, String rightAnswer) {
this.counter = counter;
this.question = question;
this.answer1 = answer1;
this.answer2 = answer2;
this.answer3 = answer3;
this.answer4 = answer4;
this.rightAnswer = rightAnswer;
}
}
For an improved approach, I suggest you look at "varargs" for the questions. Since you have a variable number of questions, you can put String ... questions
as the last constructor argument (so rightAnswer
has to go before).
public class Quiz {
private int counter;
private String question;
private String rightAnswer;
private String[] answers;
public Quiz(int counter, String question, String rightAnswer, String... answers) {
this.counter = counter;
this.question = question;
this.rightAnswer = rightAnswer;
this.answers = answers;
}
public static void main(String[] args) {
new Quiz(1, "one plus one", "two", "one", "two", "three");
new Quiz(1, "one plus one", "two", "one", "two", "three", "four");
new Quiz(1, "one plus one", "two", "one", "two", "three", "four", "five");
}
}
Note that answers
is now a string array String[]
and you can reference answers.length
, answers[0]
and so on.
One more comment: calls to no-args super()
in a constructor are usually superfluous (you don't need them).
Overloading constructor VS passing null while createing objects in Java
Using multiple constructors is the best. Many standard API libraries also have implemented it.
Also It makes code loosely coupled and not a good practice to create the object by passing explicit 'null' value.
Case 2 increases chances of High coupling.
Apart from main question :
Read More: Best way to handle multiple constructors in Java
EDIT:
Its better practice to use named factory methods to construct objects as they're more self-documenting than having multiple constructors. [Effective Java by Joshua Bloch]
Related Topics
Booleans, Conditional Operators and Autoboxing
Java Error: Only a Type Can Be Imported. Xyz Resolves to a Package
Multi-Project Test Dependencies with Gradle
Purpose of Default or Defender Methods in Java 8
Difference Between Spring @Controller and @Restcontroller Annotation
What Is Recommended Way for Spawning Threads from a Servlet in Tomcat
What Causes a Java.Lang.Stackoverflowerror
Java Type Inference: Reference Is Ambiguous in Java 8, But Not Java 7
Lambda Expression and Generic Defined Only in Method
Simple Division in Java - Is This a Bug or a Feature
Can a Java File Have More Than One Class
In Java, How to Check If a String Contains a Substring (Ignoring Case)
Sorting Using Comparator- Descending Order (User Defined Classes)