this code from ArrayList source:
public ArrayList() {
super();
this.elementData = EMPTY_ELEMENTDATA;
}
this code from AbstractList source:
protected AbstractList() {
}
What does super() do?
In general, super will invoke its parent constructor with matching arguments. In this case, because AbstractList has an implicit no-arg constructor, we use super() with no arguments to invoke the implicit no-arg constructor.
As to why - there's really no reason to do it in this case, if there's no requirement to set fields in the parent class. This may have been a case of an older style of programming.
It does no harm, and it's self-documenting; it's explicit in that it calls its parent's constructor. Although, I will note that the Javadoc for that constructor calls out its invocation usefulness:
/**
* Sole constructor. (For invocation by subclass constructors, typically
* implicit.)
*/
You're more likely to see implicit invocations of that constructor than you are explicit.
super() call parent constructor.
super() is never needed, however it is not a bad habit to write it, because it is good for readability - it reminds you that parent constructor is called.
See this question When do you need to explicitly call a superclass constructor?
Related
I am learning about super() constructor and I ran into this statement:
Since the inherited instance variables should be initialized, and the base class constructor is designed to do that, then an explicit call to super() should always be used.
What does this statement mean?
Except for the fact that implicit call can result in an error if the base class has not defined a no-argument constructor?
I think the quoted paragraph is a little bit misleading because you only need to explicitly call a parametrised super() if you are not happy with the unparametrised implicit super() call.
You would also have to do a parametrised super() call if the base class only has parametrised constructors.
This sentence you quoted doesn't explicitly say that you need to have 0 argument constructor in your class. The point of the sentence is that all the variables that are part of parent class should be initialized and you initialize those variables with a constructor, therefore you should call parent class constructor inside of your child class constructor. Doesn't matter what is the number of arguments of parent class constructor.
This question already has answers here:
Why call super() in a constructor?
(8 answers)
Closed 5 years ago.
I'm a Java beginner learning about Java compiler rules as below:
If the class has no super class, extend it to Object class
If the class has no constructor, add a default no-parameter constructor
If the first line of the constructor is not "super()" or "this()", add "super()" to call the default constructor of the super class.
I understand that all objects we create are derived from the super class Object.
My question is what does the constructor in the Object class do when called?
Edit: My question is about what the constructor does in the class Object? I'm aware that subclasses call superclass's constructor by default.
For example, I have the following code (where I explicitly extend to Object and call super() to illustrate what the compiler does). My question is, what does the call to super() do?
public class Person extends Object
{
private String name;
public Person(String n)
{
super();
this.name = n;
}
}
My question is, what does the call to super() do?
It calls the default constructor for java.lang.Object. And to answer what you seem to be really asking, from the Java Language Specification, #8.8.9
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.
Note the final paragraph.
All Java classes that don't have any explicit superclass, extend from Object, except for Object itself. There's no need to make it explicit in your code, the compiler will take care of.
Also, the super() call in the constructor will invoke the constructor of Object. If you look at the implementation, you'll see that Object doesn't have any constructor at all, so it'll use an implicit empty constructor which does nothing. Details such as constructing a vtable to make sure that the inherited methods are there to use or initialising the object's monitor are not part of the constructor but are performed by the JVM implementation when the new operator is called.
public Object() {
}
The Object class has few methods that come handy in most of the classes. For example, the infamous toString() is implemented in the Object class. Also, the hashCode() is implemented there.
I'd recommend you to have a deep look at the Object.class file to understand what methods are inherited in every single Java class.
Regarding your 3 rules at the top, are "good" for academic purposes but never used in reality. You'll never see an explicit extends Object, and only call the super() or this() when you need to overwrite the default behaviour.
Also, avoid abusing of inheritance and use more composition (implement an interface), although, it depends on the every use case.
For example, I have the following code (where I explicitly extend to
Object and call super()). My question is, what does the call do
super() do?
Actually, Object() does nothing.
Now you should not reduce the constraint to invoke super() (with args or not) for any subclass constructor to the case where you have a class that doesn't extend a class explicitly.
This case is the only one where invoking super() may seem not really useful.
But as soon a class extends a class distinct from Object, this constraint makes really sense as the child construction has to apply first its parent construction.
But the language specifies this point in a general way. It has no exception for classes that extend directly Object.
Probably because, it makes things more simple and that is not a real constraint as the compiler adds for you the call to the super default constructor : super().
In java, can a contructor in a class call an overloaded constructor of its superclass (say if we wanted to make that call explicitly and deliberately). I know that a constructor in a class makes implicit call to no-arg default constructor of superclass ( with super (); ) . but suppose I make a call to an overloaded superclass constructor (say super(String s); ) , then my question is, Is this possible? And if this is possible, then is a call to super() still made ahead of super(String s)or not and what are its implications? Also can two constructors from same class one no-arg and one overloaded call each other? Will they be caught in a loop if they do so?
You can get the answer in its official tutorial:
https://docs.oracle.com/javase/tutorial/java/IandI/super.html
Read this specifically:
The syntax for calling a superclass constructor is
super();
or:
super(parameter list);
With super(), the superclass no-argument constructor is called. With super(parameter list), the
superclass constructor with a matching parameter list is called.
Note: If a constructor does not explicitly invoke a superclass
constructor, the Java compiler automatically inserts a call to the
no-argument constructor of the superclass. If the super class does not
have a no-argument constructor, you will get a compile-time error.
Object does have such a constructor, so if Object is the only
superclass, there is no problem. If a subclass constructor invokes a
constructor of its superclass, either explicitly or implicitly, you
might think that there will be a whole chain of constructors called,
all the way back to the constructor of Object. In fact, this is the
case. It is called constructor chaining, and you need to be aware of
it when there is a long line of class descent.
So to answer your question:
Yes, it is possible, and doable. When you explicitly invoke super constructor with arguments, then only that constructor is invoked.
And, make sure the super constructor invocation is the first line in your constructor, otherwise a compiler error will show.
*****EDITED*****
And, you invoke one specific super class constructor, implicitly or explicit, only. When that superclass constructor is called no other superclass constructors are called, unless it is called within your called superclass constructor. Meanwhile, it is not possible to compile if in the same class multiple constructors call each other recursively - it will be rejected by your compiler.
Hope this helps.
I learned that when constructing an object, super() will be called, whether you write it in the constructor or not. But I noticed that in some code, the super() method is called explicitly. Should I be calling super() implicitly or explicitly in a constructor? What's the difference?
Should I call the super() method implicitly or explicitly in a constructor? What's the difference?
There is no semantic difference between calling super() or not, and no performance difference either.
This is purely a cosmetic issue. Make up your own mind ... or go with what (if anything) your project's adopted style guide says.
On the other hand, if the super you need to call has parameters, then it does matter that you call it explicitly. And if the superclass doesn't have a no-args constructor, then you can't use super(), either explicitly or implicitly.
There is no difference if the discussion is around no-argument super() constructor.
Java calls super() implicitly for all your base class constructors if not called explicitly. Remember Java only calls super class no-argument constructor always.
In some cases, as a developer you may want to call argument-based super constructor. In those cases, you have to explicitly call argument-based super constructor eg: super(arg1, arg2, ...)
IMO, avoid calling no-argument super() constructor since it neither have any impact on logic nor improves readability.
I'm learning Java (2nd year IT student) and I'm having a little problem. With inheritance to be precise. Here's the code:
class Bazowa
{
public Bazowa(int i)
{
System.out.println("konstruktor bazowy 1");
}
public Bazowa(int j, int k)
{
System.out.println("konstruktor bazowy 2");
}
}
class Pochodna extends Bazowa
{
/* Pochodna()
{
System.out.println("konstruktor pochodny bez parametru");
} */
Pochodna(int i)
{
super(i);
System.out.println("konstruktor pochodny z parametrem");
}
}
So, the Pochodna class extends the Bazowa class, and my exercise is to make a superclass that has only constructors with parameters and a subclass that has both types (with and without).
When I comment the first constructor in Pochodna class, everything works fine, but I don't really know how to make it work without commenting that part. I guess that I have to somehow call the constructor from the first one, but don't have an idea how to do that.
Any help would be appreciated,
Paul
Your first constructor from Pochodna calls by default super(), a constructor which you do not have in Bazowa.
You should either call one of the base constructors with 1 or 2 params in Pochodna(), or create a constructor with no parameters in your base class.
EDIT: Since you said you are learning Java, I will add some extra explanations to my answer.
Every class must have a constructor, so when you do not declare one explicitly, the compiler does so for you, creating a default constructor with no parameters. This constructor won’t be added if YOU declare constructors explicitly.
In inheritance, the child class is a “specialization” of the parent. That means that the child class contains the attributes and behavior of the parent class and extends on them. But you do not declare the parent elements again (unless you really want to overwrite stuff). So, when you create an instance of the child, somehow the elements taken from the parent must also be initialized. For this you have the super(...) construct.
The first thing that must be in a child constructor is a call to super(...) so that the elements taken from the parent are properly initialized before the child tries to do something with them (you can also have a call to another of child’s constructor this(...) – in this case, the last child constructor in the calling chain will call super(...) ).
Because of this, the compiler will again add a default call to super() – with no parameters – for you when you do not do so yourself in the child.
In the first constructor of Pochodna, since you did not call super(i) or super(j, k) yourself, a call to super() was placed by default. But in the parent class you explicitly specified constructors, so the default was not created by the compiler. And from here the exception, you end up calling a constructor that does not exist.
Hope this makes it easier to learn Inheritance. Cheers.
You need to specify something like this:
Pochodna()
{
super(0);
}
The trick here is that since you specify a constructor for the superclass the compiler doesn't create a no-arg constructor for you. When you make your zero-arg constructor in the superclass it tries to call the no-arg constructor in the subclass and fails to find anything.
In short, calling another constructor (either in the superclass or in the same class) in your constructor is not optional. Either you specify another constructor explicitly or a call to the superclass' zero-arg constructor will get inserted.
Since the base class does not have a parameterless constructor, you will need to call a constructor explicitly using super, providing some kind of a default value.
For example:
Pochodna()
{
super(0);
System.out.println("konstruktor pochodny bez parametru");
}
Alternatively, you can create a protected parameterless constructor in the base class. It will not be directly accessible from the outside, but derived classes will be able to use it.
Other answers handle the call to the super constructor.
Note that you could also do this:
Pochodna() {
this(0);
System.out.println("konstruktor pochodny bez parametru");
}
which would call your other constructor for Pochodna. Just another option. Study the output to understand what is happening.
As the default constructor is not present in the parent, you have to call the other constructor in the child constructor:
Pochodna() {
super(10);
}