I just noticed in the codebase of a very large project I am assigned at work, a particular class has no constructor. Its subclass though, calls super().
Can someone please explain what is going when a subclass calls super(), but there is no constructor in the parent?
(I can guess that the effect is like calling an empty constructor, but I am wondering if there is anything else going on behind the scenes).
If you do not have any parameterized constructor and I strictly mean no constructor then and only then java will add a default constructor(One with no parameters) for you.
Each constructor must call a constructor of it's super class. You cannot perform any other action in the subclass constructor untill all constructors of superclasses up the inheritance tree are called. Hence this call must be the 1st line of your subclass constructor If you do not provide one again java does that for you.
Refer
Why does this() and super() have to be the first statement in a constructor?
If a class doesnt having any constructors means it is gifted with empty constructor by the java compiler.
If you place the empty constructor , then the compiler will not because it is already mentioned by you.
Now If you want your own constructor with your own parameters, Then there will not be any default constructor by the java compiler
Check this for more info on constructors
Subclass constructor always call its parent constructor first before executing any statement. If there is no consturctor in parent class then whether you call it or not explicitly, super() call will be added in the code by java compiler and hence will be executed by JVM.
The java compiler will provide a default no argument constructor without a body when a class doesn't declare any constructors. Calling super() in a base class constructor will invoke that default constructor.
Can someone please explain what is going when a subclass calls
super(), but there is no constructor in the parent?
If parent class doesn't have any constructor then java compiler will call the default constructor of it. If you don't want to call default constructor then you can create your own empty constructor in that class.
Compiler add a default constructor with no parameter into your class if you do not provide it explicitly. So in your case it is calling default constructor.
Related
default constructor invoke no_argument constructor in super class reference
and this last constructor used to instantiate object from this class,How ? i mean what does superclass constructor body exactly do ?
example
public class Child extend Fragment {}
if i tried to instantiate this class Child
Child a = new Child() ;
while compiling compiler invoke no-argument constructor in Fragment class .
in android.app package i found that no-argument constructor has no body
public Fragment() {}
Question how could this constructor be useful ? it do nothing !
P.S
i mean by
how could this constructor be useful?
how does it instantiate its class although it empty , where is the code that instantiate super class?
Question how could this constructor be useful ? it do nothing !
The purpose of a constructor, whether empty or not, is to provide an instance of the class. The constructor body, if it exists, may further do additional operations necessary when first creating the instance.
The constructor may not be doing anything itself but it returns an instance, on which you may further call public methods defined in the class.
For example, in your mentioned Fragment class, let's suppose there is an attach() method. If the attach() method is non-static, you will need to create an instance (using the empty constructor) to call the attach() method on it irrespective of whether the constructor does anything or not.
how does it instantiate its class although it empty
A constructor doesn't need any code in its body to be instantiated.
Calling new ClassName() (with appropriate parameters, if any) is enough. It is the job of JVM to create the object at runtime. You don't need to write any specific code inside a constructor for that. That extra code, if you wish, can help the instance start off with a specific state by setting some fields or calling methods, etc.
where is the code that instantiate super class?
A constructor in a subclass (or any class, for that matter) only generates an instance of that class. It doesn't need to instantiate its super class. You may call the super class constructor (using super()) if it has some important initialization code, but it's not compulsory. Also, subclasses don't inherit constructors from super classes. But they do inherit the public and protected fields and methods.
Regarding the Fragment class, you have have some confusion regarding its use which can be clarified here.
The syntax for calling a superclass constructor is
super();
or:
super(parameter list);
Question how could this constructor be useful ? it do nothing !
The super constructor could be used to initialized properties common for all subclasses. If it's empty it still can be used by reflection API.
Fragment.class.getConstructor().newInstance();
or
Child a = new Child() ;
a.getClass().getSuperclass().getConstructor().newInstance();
the last line explicitly invokes a constructor of the superclass.
an empty constructor (aka default constructor) means only that an instance can be created without any further work. This can be due to framework requirements or the instantation is ok with the default values for the attributes.
If the empty constructor is the only constructor in the class, it is not required to write it, its there by default.
Although if there are other constructors (with parameters), one must explicitly state the default constructor.
As I was preparing for an interview about OOP, I came across this question.
A inherits form B. B inherits from C.
Will initializing A invoke constructor of C?
What I know is that a constructed is not inherited. We have to use the super keyword to refer to the parent's constructor. Am I right?
The constructor of a subclass will first invoke the constructor of its super class. If a class has several ancestors, these calls will be stacked until the constructor of the top ancestor is called. Then, it will continue executing the constructor of the next ancestors until all the constructor of the ancestors were executed. You can infer from here that every time you create an object, the constructor of Object class is invoked, always.
Note that if you don't add the call to super() in the subclass constructor, the compiler will add it for you automatically. If there's no default constructor for the super class and you don't specify the call to the specific constructor of the super class in the constructor of the subclass, then you will get a compiler error.
All these rules are stated in JLS.
In the world of Java, when you are extending another class, you only see your direct super class' constructor. The super class is supposed to proper encapsulate the super-super class constructor.
There will always be an implicit call to the constructor of the base class. In your case, the constructor of C will be called first, then the constructor of B and finally the constructor of A.
Using super is useful when you have defined overloaded constructors, and you want to call a specific one.
I know that in a derived Java class one may call the super constructor as the first command in the child's constructor. Python for example kindly allows in this case to do some custom logic before calling the super constructor.
My question is: In Java is there any way to achieve this, calling some commands before calling the super constructor? If not, what is the "Java way" of doing this in general?
Example use case: I am writing a game, and in the child class constructor I need to load some assets (only for that child class, not statically), and pass them to the parent constructor.
You can call static methods within the call to super() (e.g. super(initSomething()); if that method is static).
However if your logic is too complicated it might be best to use a static factory method which can then do a little bit more custom initialization before calling into a (private) constructor.
Invocation of a superclass constructor must be the first line in the subclass constructor.
Taken from here. So, no you cannot perform logic before you call the super class's constructor in the way you asked.
In ArrayList.java, why is the ArrayList(int initialCapacity) constructor calling super()?
I know it is trying to call its super class's default constructor, i.e AbstractList(). But there is absolutely no implementation in AbstractList().
protected AbstractList() {
}
Anyway, the super class's default constructor will be called in this case.
What is the need to write super()?
The fact that the AbstractList constructor does nothing, doesn't mean that it doesn't have to be called. To be more precise an empty constructor doesn't actually do nothing. The JVM still does things when a constructor is called even if it's empty. You always have to call a constructor when creating objects and each constructor always has to call a superclass constructor first (except Object of course).
If you wouldn't write super() in the constructor of ArrayList, it would still be called implictly by default. Writing it explictly is just considered good style by some developers. Same goes for declaring an empty default constructor, which also would be default. Altough there is a little inconsistency here. If they would have stuck to the same convention I guess it should be
protected AbstractList() {
super();
}
There is no need to write it - super() is superfluous, but it does no harm.
Good developers (like yourself, from the sound of it) who know the spec will understand that super() is called implicitly before any other code in the constructor, if not specified explicitly.
like this:
public class class1 {
public void xxx(){
super.getXXX();
super().getXXX();
}
}
Both are used in a subclass as a way to invoke or refer to its superclass.
super() is a method call you make inside a constructor or inside an overridden method to invoke the superclass's constructor or the superclass's overridden method. The super() call can also take arguments in these cases.
Note that since all classes by default at least inherit from Object, you can always call super() inside a constructor (it must be the first statement in the constructor though). This super() call is in fact ordinarily inserted by the compiler into your no-arg constructor by default.
This can get tricky however if the superclass doesn't have a no-arg constructor though, in which case your call to super() will fail without the appropriate args. A no-arg constructor is ordinarily generated by default however so you don't have to worry about it, but it won't be automatically generated if you've explicitly define another constructor with args, so that's when you may need to explicitly define one yourself.
super without the parens on the other hand is simply a reference to the superclass itself, like any other variable. It can be used to invoke any accessible method in that class or to refer to any of the class's accessible fields, just like you would with any other reference. Eg: super.doSomething() or super.x
Every class in java has a Superclass. When you use the super keyword, you are referring to super class, and the dot operator on super will give you access to the Super class's properties and methods.
super() is the constructor of super class. When you override the constructor in a subclass, you have to call super() before you can execute your own logic, and if you don't, the compiler, on your behalf, will insert a call to the no-args constructor. (Sometimes, there isn't one, and the code fails in compilation)
While in Java, calling the constructor gives you an instance of the class, it isn't the same thing when you do a super(), because there isn't a separate instance of the super class getting created when you do a super(). Hence, while MyClass().doSomething() is a perfectly valid call, super().doSomethingElse() is not.