I've come across an interesting snippet of Java code. I researched what newInstance() is, and it's meant to be a way to avoid calling a constructor and create a new instance of an object. But looking at the example code I don't understand one thing: Why is there no constructor needed?
public class SimpleContentFragment extends WebViewFragment {
protected static SimpleContentFragment newInstance(String file) {
SimpleContentFragment f=new SimpleContentFragment();
Bundle args=new Bundle();
args.putString(KEY_FILE, file);
f.setArguments(args);
return(f);
}
}
No where else in this code is there a constructor created. There is no
public SimpleContentFragment() {
// Required empty public constructor
}
as I would expect.
So could you clarify what is going on in the static method with newInstance? How come it can call new SimpleContentFragment() when the constructor was never written?
This is because Java will create a default, no-arguments constructor if none is provided. It will set all reference fields to null, numeric types to 0, and booleans to false, and invoke the superclass constructor.
JLS 8.8.9:
If a class contains no constructor declarations, then a default
constructor is implicitly declared. The form of the default
constructor for a top level class, member class, or local class is as
follows:
The default constructor has the same accessibility as the class (§6.6).
The default constructor has no formal parameters, except in a non-private inner member class, where the default constructor
implicitly declares one formal parameter representing the immediately
enclosing instance of the class (§8.8.1, §15.9.2, §15.9.3).
The default constructor has no throws clauses.
If the class being declared is the primordial class Object, then the default constructor has an empty body. Otherwise, the default
constructor simply invokes the superclass constructor with no
arguments.
Related
This question already has answers here:
I don't understand this part in Oracle docs?
(4 answers)
Closed 3 years ago.
According to Oracle's documentation https://docs.oracle.com/javase/tutorial/java/IandI/super.html, its written that If the super class does not have a no-argument constructor, you will get a compile-time error.
But in my case, I have a super class without any constructor. In my baseclass, I am writing super() in its no-arg constructor. Here, I don't have a no-arg constructor in super class, but its not showing any error.
class Person {
}
/* subclass Student extending the Person class */
class Student extends Person {
Student() {
// invoke or call parent class constructor
super();
System.out.println("Student class Constructor");
}
}
// Driver class
class Practice {
public static void main(String[] args) {
Student s = new Student();
}
}
This assumption is wrong:
Here, I don't have a no-arg constructor in super class, but its not showing any error.
If a class has no explicit constructor then it will have an implied no-argument constructor.
Please check out this related Stack Overflow question for more: Java default constructor
Also check out the Java Language Specification: §8.8.9. Default Constructor:
If a class contains no constructor declarations, then a default constructor is implicitly declared. The form of the default constructor for a top level class, member class, or local class is as follows:
The default constructor has the same accessibility as the class (§6.6).
The default constructor has no formal parameters, except in a non-private inner member class, where the default constructor implicitly declares one formal parameter representing the immediately enclosing instance of the class (§8.8.1, §15.9.2, §15.9.3).
The default constructor has no throws clauses.
If the class being declared is the primordial class Object, then the default constructor has an empty body. Otherwise, the default constructor simply invokes the superclass constructor with no arguments.
I am trying to implement a constructor for a subclass, however I keep getting "error: class, interface, or enum expected" when I compile.
My code for the overall looks like this:
public class Super{
//methods go here, no constructor.
}
Here is what I tried but it did not work:
public class Sub extends Super{
private boolean myCondition;
public Sub(boolean condition){
super();
myCondition = condition;
}
}
I would assume that I would not need to call super() in the subs constructor as the compiler should implicitly call it.
Thanks.
Every class has a constructor. If you do not specify one, you get a default constructor. JLS-8.8.9 Default Constructor
If a class contains no constructor declarations, then a default constructor with no formal parameters and no throws clause is implicitly declared.
If the class being declared is the primordial class Object, then the default constructor has an empty body. Otherwise, the default constructor simply invokes the superclass constructor with no arguments.
It is a compile-time error if a default constructor is implicitly declared but the superclass does not have an accessible constructor (§6.6) that takes no arguments and has no throws clause.
In a class type, if the class is declared public, then the default constructor is implicitly given the access modifier public (§6.6); if the class is declared protected, then the default constructor is implicitly given the access modifier protected (§6.6); if the class is declared private, then the default constructor is implicitly given the access modifier private (§6.6); otherwise, the default constructor has the default access implied by no access modifier.
So Super (a public class) has a default constructor inserted by the compiler that looks something like
public Super() {
super();
}
This question already has answers here:
Java error: Implicit super constructor is undefined for default constructor
(12 answers)
Closed 4 years ago.
I have a BaseClass in a external jar, it has a constructor setting Implementation class(JerseyClientImpl) to jerseyClient.
public BaseClass(AuthDetails auth, String ID) {
setListID(D);
this.jerseyClient = new JerseyClientImpl(auth);
}
I am extending the BaseClass to set my own Implementation class to jerseyClient , but i am getting the error mentioned. Changing the BaseClass to add default constructor is not in my control as i said its an external jar.Can you suggest how can i overcome this error.
Since BaseClass has a non default constructor, it doesn't have the automatically generated parameterless default contstructor.
Therefore your sub-class can't rely on the default constructor (since it won't be able to call the non-existing default constructor of the base class), so your sub-class must have an explicit constructor that calls the constructor of the base class.
Either a constructor with the same parameters :
public SubClass(AuthDetails auth, String ID) {
super(auth,ID);
...
}
Or a constructor without parameters that gives default values for the base-class's constructor :
public SubClass() {
super(null,"something");
...
}
In Java, if you don't explicitly provide a call to a superclass constructor as the first statement in a constructor, then it will insert an implicit call to the default superclass constructor. If there is no default superclass constructor, then you get the error you have mentioned.
The JLS, Section 8.8.7, states:
If a constructor body does not begin with an explicit constructor invocation and the constructor being declared is not part of the primordial class Object, then the constructor body implicitly begins with a superclass constructor invocation "super();", an invocation of the constructor of its direct superclass that takes no arguments.
You must explicitly call the superclass constructor, passing all arguments, with something like this:
public JerseyClientImpl(AuthDetails auth, String ID) {
super(auth, ID);
// Rest of constructor code
}
First of all, if you are writing some parameterized constructor in a class...the default no arg constructor of the class does not exist anymore.
And, when you try to create constructor of its child class, the no-arg constructor of parent class is always called first.If it doesn't exist, you get compiler error.
So, define the no arg constructor in your parent class, OR just call the parameterized constructor of parent class with some value inside the child class constructor.
I'm looking through some code that I'm working with and one bit of it strikes me in particular:
In the file there is a block:
public void prepare(){
if (this.GenericObjectID != null)
doStuff();
else{
this.GenericObjet = new GenericObject();
}
However, when I look through GenericObject.java there is no constructor at all. The code runs, but I didn't write it, so I'm not positive how (yet!). So my question is: how is this possible? What is the java compiler doing when it sees this call but then no constructor in the file that describes the object?
If there are no explicit constructors, then the compiler creates an implicit default constructor, with no arguments, that does nothing but implicitly call the superclass constructor.
Section 8.8.9 of the JLS talks about default constructors:
If a class contains no constructor declarations, then a default constructor is implicitly declared. The form of the default constructor for a top level class, member class, or local class is as follows:
The default constructor has the same accessibility as the class (§6.6).
The default constructor has no formal parameters, except in a non-private inner member class, where the default constructor implicitly declares one formal parameter representing the immediately enclosing instance of the class (§8.8.1, §15.9.2, §15.9.3).
The default constructor has no throws clauses.
If the class being declared is the primordial class Object, then the default constructor has an empty body. Otherwise, the default constructor simply invokes the superclass constructor with no arguments.
new GenericObject(); is the default constructor for the class GenericObject. It is automatically created by the compiler unless you explicitly define a constructor in your class.
This constructor will call the parent class' constructor, and will initialize class member variables to their default values.
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.
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.
The compiler doesn't ever enforce the existence of a default constructor. You can have any kind of constructor as you wish.
For some libraries or frameworks it 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 class will fail to compile.
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
}
}
AS Joachim Sauer said, 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.
Otherwise your dependency injection will fail.
Its just one scenario where i encountered the importance of default constructor
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 super or 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.
Finally, you answer the question in the title:
When is mandatory to have a default constructor along with parameterized constructor in Java?
Strictly speaking, it is never mandatory to have a default constructor. It is mandatory to have a no args constructor (either explicitly declared, or default) ... only if it is explicitly or implicitly called.
(There could be libraries / frameworks that assume that 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.)
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.
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
want to create object like case 1.
inherit this class and do not make a explicit call
super(parameter,...);
in first line of ChildClass constructor.
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.
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.
#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