Calling super() with no Superclass? - java

What happens (if anything) when a constructor calls 'super()' without having any superclass besides Object? Like so:
public class foo implements Serializable, Comparable {
int[] startPoint;
public foo() {
super();
startPoint = {5,9};
}
}
Edit: So if this does nothing, why would anyone explicitly write that in code? Would it make any difference if I just delete that line?

It is always OK to delete the line super(); from any constructor, and there is nothing particular about the constructors of classes that extend Object. The call of the nullary superclass constructor is always implied, so whether you write it down or not, you always get the exact same semantics.
Note that this means that if you omit a call to the superclass constructor that does something big, like start database connections or the whole GUI, all this will happen whether or not you actually write super();.

super() is the first call in constructor either it is done explicitly or implicitly.
(But of course you might need to change parameters to match parent's constructor.)
Your code:
public foo()
{
startPoint = {5,9};
}
What compiler sees from the code above:
public foo()
{
super();
startPoint = {5,9};
}
So super() is invoked whether you put it explicitly in your code or not.
Since all classes derive from Object class, you are calling constructor of Object with your super() call because your class doesn't have any intermediate parents.

There is always a super class called Object, so it will invoke constructor of Object

That just calls the Object() constructor, just as if you had any other superclass with a constructor that has no parameters.

As you stated, there is a super class (Object).
The default object constructor will be called.

It calls Object's constructor, which is empty (does nothing).

super() always call to the constructor to Object class if the class doesn't extends from one class.
Class Object is the root of the class hierarchy. Every class has Object as a super class. All objects, including arrays, implement the methods of this class.
Check this link

Related

Calling Object's constructor

Why should a class call the call the Objects default constructor of the class Objects when the class already has a parametrized constructor and a unparametrized constructor?
Example
public abstract class Foo{
private int dim1;
public Foo(int dim1) {
super();
this.dim1 = dim1;
}
public Foo() {
this.dim1 = 0;
}
}
2. Why isn't the super() method called in the unparametrized constructor in the example above?
What could happen if I forget or I don't want to call the constructor in the Object class with super() ?
Does it matter if the class which calls the super() method (Unparametrized Object's class constructor) is abstract or not ?
Why should a class call the call the Objects default constructor of the class Objects when the class already has a parametrized constructor and a unparametrized constructor?
Just because of you have it, it doesn't mean it gets called automatically. You have to call it and that is where object instantiation begins.
Why isn't the super() method called in the unparametrized constructor in the example above?
It is not a method. It is just invoking the super class default constructor. Do you know , if you didn't call it, the Java compiler automatically inserts that statement while giving you byte code. So you need not write that super() in child constructors unless you want to call specific constructor .
What could happen if I forget or I don't want to call the constructor in the Object class with super() ?
Don't worry. As said above, compiler inserts it for you.
Does it matter if the class which calls the super() method (Unparametrized Object's class constructor) is abstract or not ?
Yes, abstract or not doesn't matter. It just calls the super class constructor.
1) You probably shouldn't. It is unnecessary. It is an extra line of code which doesn't do anything.
2) Because explicitly calling super() is entirely unnecessary if your object does not extend a class other than Object (as all classes do). You could remove it from the first constructor and nothing would change. The code would compile identically.
3) Nothing. You're not required to do it.
4) This makes no difference.

Relating Constructor of Super Class in java

If I create an object of a sub-class with no constructors, then I know that the compiler will implicitly provide a default constructor. What if I create a constructor in the sub-class and try to access the super class constructor using the super keyword, and, now, the super class has no constructor in it. Will the compiler provide a default constructor for the super class as well?
Yes, if there is no specified constructor, there is always default empty constructor
Does the compiler provides a default constructor for the super class also???
The default constructor will be there whether or not there is a subclass that needs it. The default is supplied when the parent is compiled, not later.
...What if I created sub class Constructor and trying to access the super class constructor using the super keyword,and the super class has no constructor in it.
But it does: The default one.
It goes like this.
Lets speak about Object which is the supermost class in java, If you open an editor and just make a class, then it is presumed that It is extending Object. Every class in Java extends from Object. If you do not write your own constructor then Compiler will provide one.
But if you write your own constructor let's say a constructor with one argument, compiler will not provide you with any constructor.
Now lets say taht you extend the above class, then compiler will complain you saying that the superclass does not have a default constructor rather a custom constructor so you need to make one constructor for this child class since first constructor which is called starts from the supermost class that is OBJECT and then proceeds down the line.
Hope this answers comprehensively,
Thanks.
Yes the super always occurs even if you didnt explicit declare
public class FatherTest {
}
public class SonTest extends FatherTest{
public SonTest(String sonName){
super(); // this will always occurs
}
}
If you don't write a constructor for a class, the compiler will implicitly add an empty one for you.
That means this:
public class X {
}
is identical to this:
public class X {
public X() {
// there's also an implicit super(); added here, but that's not directly relevant
}
}
If the super class doesn't have explicit constructor, then an implicit default constructor will be added to it. So your super() will invoke that.
If the super class only have some constructors with parameters. Then super() in the sub-class won't compile. You have to explicitly use one of the defined super-class constructor super(param1, param2, ...), since super() will be called if you don't call it.

A call to a static method within the parameter list of super() is valid in Java. Why?

Let's look at the following code snippet in Java.
package trickyjava;
class A
{
public A(String s)
{
System.out.println(s);
}
}
final class B extends A
{
public B()
{
super(method()); // Calling the following method first.
}
private static String method()
{
return "method invoked";
}
}
final public class Main
{
public static void main(String[] args)
{
B b = new B();
}
}
By convention, the super() constructor in Java must be the first statement in the relevant constructor body. In the above code, we are calling the static method in the super() constructor parameter list itself super(method());.
It means that in the call to super in the constructor B(), a method is being
called BEFORE the call to super is made! This should be forbidden by the compiler but it works nice. This is somewhat equivalent to the following statements.
String s = method();
super(s);
However, it's illegal causing a compile-time error indicating that "call to super must be first statement in constructor". Why? and why it's equivalent super(method()); is valid and the compiler doesn't complain any more?
The key thing here is the static modifier. Static methods are tied to the class, instance methods (normal methods) are tied to an object (class instance). The constructor initializes an object from a class, therefore the class must already have been fully loaded. It is therefore no problem to call a static method as part of the constructor.
The sequence of events to load a class and create an object is like this:
load class
initialize static variables
create object
initialize object <-- with constructor
object is now ready for use
(simplified*)
By the time the object constructor is called, the static methods and variables are available.
Think of the class and its static members as a blueprint for the objects of that class. You can only create the objects when the blueprint is already there.
The constructor is also called the initializer. If you throw an exception from a constructor and print the stack trace, you'll notice it's called <init> in the stack frame. Instance methods can only be called after an object has been constructed. It is not possible to use an instance method as the parameter for the super(...) call in your constructor.
If you create multiple objects of the same class, steps 1 and 2 happen only once.
(*static initializers and instance initializers left out for clarity)
Yep, checking the JVM spec (though admittedly an old one):
In the instance init method, no reference to "this" (including the implicit reference of a return) may occur before a call to either another init method in the same class or an init method in the superclass has occurred.
This is really the only real restriction, so far as I can see.
The aim of requiring the super constructor to be invoked first is to ensure that the "super object" is fully initialized before it is used (It falls short of actually enforcing this because the super constructor can leak this, but that's another matter).
Calling a non-static method on this would allow the method to see uninitialized fields and is therefore forbidden. A static method can only see these fields if it is passed this as argument. Since accessing this and super is illegal in super constructor invocation expressions, and the call to super happens before the declaration of any variables that might point to this, allowing calls to static methods in super constructor invocation expressions is safe.
It is also useful, because it allows to compute the arguments to the super constructor in an arbitrarily complex manner. If calls to static methods weren't allowed, it would be impossible to use control flow statements in such a computation. Something as simple as:
class Sub extends Super {
Sub(Integer... ints) {
super(Arrays.asList(ints));
}
}
would be impossible.
This is one situation where the java syntax hides what's really going on, and C# makes it a bit clearer.
In C# your B would look like
class B : A {
public B() : base(method()) {
}
private static String method() {
return "method invoker";
}
}
Although the java syntax places super(method) within the constructor it's not really called there: All the parent initialization is run before your subclass constructor. The C# code shows this a little more clearly; by placing super(method()) at the first line of the java constructor you're simply telling java to use the parameterized constructor of the super class rather than the parameterless version; this way you can pass variables to the parent constructor and they'll be used in the initialization of the parent level fields before your child's constructor code runs.
The reason that super(method()) is valid (as the first line in a java constructor) is because method() is being loaded with the static elements--before the non-static ones, including the constructors--which allows it to be called not only before B(), but before A(String) as well. By saying
public B() {
String s = method();
super(s);
}
you're telling the java compiler to initialize the super object with the default constructor (because the call to super() isn't the first line) and you're ready to initialize the subclass, but the compiler then becomes confused when it sees that you're trying to initialize with super(String) after super() has already run.
A call to super is a must in java to allow the parent to get initalized before anything with child class starts.
In the case above, if java allows String s= method(); before the call to super, it opens up flood gate of things that can be done before a call to super. that would risk so many things, essentially that allows a half baked class to be used. Which is rightly not allowed. It would allow things like object state (some of which may belong to the parent) being modified before it was properly created.
In case of super(method()); call, we still adhere to the policy of completing parent initialization before child. and we can use a static member only, and static member of child classes are available before any child objects are created anyways. so the method is avilable and can be called.
OK..i think, this one could be relevant that, if we are calling some member with Super, then it first try to invoke in super class and if it doesn't find same one then it'll try to invoke the same in subclass.
PS: correct me if i'm wrong

Why should the derived class constructor always access base class constructor?

I saw this question in one of my question papers:
Why should the derived class constructor always access base class constructor?
I'm wondering whether the question is valid?
So that you may have a valid object of type "Base" before you start messing with the inherited functionality in your derived object!
It's not valid. There's no 'should' about it: it must, and the compiler enforces it, by calling the base class's default constructor if it exists, and giving you a compile error if it doesn't, which forces you to call one of the existing constructors.
There is one exception to always, a default constructor in a superclass isn't usually called explicit.
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.
Because the base class may do work you are not aware of.
Because the base class may have members that require initialization.
Since the derived class constructor wants to inherits from the base class constructor, it is necessary to call the base class constructor. Otherwise, if you don't, you will not inherit values initialised in base class constructor.
Calling a superclass constructor is not a must but a should paired with a strong advise - as long as the superclass has a default constructor. Otherwise the compiler forces you to call at least one of the superclasses constructors.
If the default constructor is present, it's called anyway, even without an explicit super() statement in the subclasses construtor.
A visible part of class construction is the initialization of fields. But there's more under the hood (memory allocation, registration, etc). All this has to be done for all superclasses when a derived class is created.
You do not need to call constructor when there is a default constructor (i.e a no-argument constructor) present in the base class. When there is a constructor with arguments present and no default constructor, then you don't need to declare a constructor in the child class.
You only need to initialize the child class constructor when there is no default constructor present in the parent class.
Example :
class A {
public int aInstanceVariable;
public A(int aInstanceVariable) {
this.aInstanceVariable = aInstanceVariable;
}
}
class B extends A {
// In this case we have to call super in base class constructor
}
However, when public A() {} is present in class A, there is no need to initialize the child class constructor.

Class inheritance problem in Java, constructors with and without params

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);
}

Categories

Resources