recursion with super keyword in java - java

Consider the following code :
public class TestClass
{
TestClass()
{
super();
System.out.printf("yes it is called");
}
public static void main(String[] args)
{
new TestClass();
}
}
Now as anonymous object is created , it calls the constructor. Now with super , it agian calls it self and again the process repeats . This should create infinite recursion.But this is not what happens . Why ?

This is not recursion. In a constructor, calling super(); calls the superclass constructor, not itself.
If you were to say this(); inside that constructor, then the compiler would catch "recursive constructor invocation" as a compiler error.

super() in your case just calls new Object() (all java classes inherit from the Object class), something that would happen anyway. No recursion here

super() is in reference to the superclass, you are calling Object's constructor.
If you were to make this infinite recursion, you would use this
public class SomeClass {
public SomeClass() {
this(); //recursion!
}
}
Of course, this is a compilation error.

Related

Can't seem to understand complex polymorphism

I'm studying CS and we have questions about polymorphism that I cant wrap my mind around. Here is an example:
public class AA{
public AA(){
foo();
}
private void foo() {
System.out.print("AA::foo ");
goo();
}
public void goo(){
System.out.print("AA::goo ");
}
}
public class BB extends AA{
public BB(){
foo();
}
public void foo(){
System.out.print("BB:foo ");
}
public void goo(){
System.out.print("BB::goo ");
}
public static void main(String[] args){
// Code goes here
}
}
When in void main i add the line:
AA a = new BB();
it goes first AA constructor prints AA:foo but then goo() sends it to BB's goo, why so?
Simple polymorphism such as "Animal -> cat/spider/dog" is easy to understand but when it comes to this I'm just lost. Can you guys give me any tips how to read this code? What are the rules are?
EDIT: there is no #Override annotation because this is a question from an exam.
Explanation
public class AA {
private void foo() { ... }
^^^^^^^
}
Polymorphism is not applied to private methods. A subclass does not inherit private methods, so they cannot be overridden:
A class C inherits from its direct superclass all concrete methods m (both static and instance) of the superclass for which all of the following are true:
m is a member of the direct superclass of C.
m is public, protected, or declared with package access in the same package as C.
No method declared in C has a signature that is a subsignature of the signature of m.
Java Language Specification - 8.4.8. Inheritance, Overriding, and Hiding
Therefore, the foo() call from the A constructor doesn't invoke BB#foo, it calls AA#foo.
But the goo() call within AA#foo refers to the overridden method BB#goo. Here, with public methods, method overriding and polymorphism were applied.
It's a bit tricky, so I would recommend you put the #Override annotation everywhere it's supposed to be.
public class BB extends AA {
#Override // it doesn't compile - no overriding here
public void foo() { ... }
#Override // it does override
public void goo() { ... }
}
It also might be helpful to detect another problem:
Programmers occasionally overload a method declaration when they mean to override it, leading to subtle problems. The annotation type Override supports early detection of such problems.
If a method declaration in type T is annotated with #Override, but the method does not override from T a method declared in a supertype of T, or is not override-equivalent to a public method of Object, then a compile-time error occurs.
Java Language Specification - 9.6.4.4. #Override
Illustration
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.
Java Language Specification - 8.8.7. Constructor Body
To put it simply,
public BB() {
foo();
}
turns into
public BB() {
super();
foo();
}
Keeping super(); in mind, we can make the next illustration:
new BB()
AA() // super(); -> AA constructor
A#foo() // private method call
B#goo() // polymorphic method call
BB() // BB constructor
B#foo() // plain method call
It's explained very well in the official docs:
https://docs.oracle.com/javase/tutorial/java/IandI/super.html
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.
So, the Java compiler is adding super() without args for you.
In fact, if the class you are extending doesn't have a default constructor you will be required to call this constructor with args before.
Otherwise, the reason why AA:goo is not being called is because is override by BB even if it doesn't have the #Override annotation, if you want to see that call you need to use super(); in your b:goo method. In fact, the foo is not override because it private so it's not possible to override it, if you try to add the annotation #Override you'll se you have a compilation failure.
AA::foo() is private so AA::foo() and BB::foo() aren't the same.
new BB()
will call AA::Constructor first, calling AA::foo().
AA::foo() call goo() and since you instantiated BB class it'll be BB::goo().
Please use "override" keyword on method when you want to do something like this
There is also a serious design flaw in the example code: it is calling an overridable method from a constructor. This means that object BB might not be fully initialized at the time that this method is called on it. For example:
public class AA{
public AA(){
foo();
}
private void foo() {
System.out.print("AA::foo ");
goo();
}
public void goo(){
System.out.print("AA::goo ");
}
}
public class BB extends AA{
private Date timestamp;
public BB() {
super();
foo();
timestamp = new Date();
}
public void foo() {
System.out.print("BB:foo ");
}
public void goo() {
// goo() gets called before timestamp is initialized
// causing a NullPointerException
System.out.print("BB::goo " + timestamp.getYear());
}
public static void main(String[] args){
AA obj = new BB();
}
}
Remember this: NEVER CALL AN OVERRIDABLE METHOD FROM A CONSTRUCTOR (even not indirectly as in this example)
Polymorphism is Simple yet Confusing at times when we use different set of names [Which is the case here].
Polymorphism is basically a Parent Child Relationship. Key here is, if you are trying hard to place the names of the classes, use yourself instead i.e. give comment line next to class names as below
public class AA{} //your Parent name
public class BB extends AA{} // yourself i.e. your name
When it comes to the code like this, AA a = new BB(); , decode the code as below:
BB is you, AA is your parent.
new keyword is with YOU(i.e. BB), so a new object of YOU would be created or born. In order to for YOU to born, without your parents(i.e. AA), you cannot exist and so, first they will be born or created (i.e. AA constructor would run). Once your Parents (i.e. AA) are created, then it is time for YOU to born(i.e. BB constructor would run).
In your example,
public AA(){
foo(); -- line A
}
private void foo() {
System.out.print("AA::foo ");
goo(); -- line B
}
public void goo(){
System.out.print("AA::goo "); -- line C
}
As I told earlier, Line A would be called when you say AA a = new BB(); as Line A is in Constructor of AA, Line A calls foo() method and so the control lands in foo(), prints "AA::foo " and executes Line B. Line B calls goo() method and so on it reaches Line C. After Line C is executed, there is nothing left to execute in AA constructor (i.e. Object is created) and so the control flows down to the child Constructor ( As parent is created, it is time for the child to born) and so the child Constructor would be called next.
For Students/Beginners, I strongly recommend to go through Head First Java Edition. It really helps you in laying the Java Foundation Strong.

What's the difference between an instance initializer and a constructor?

Just wondering about the reason of compiling code like this:
class MyClass extends AnotherClass {
{
MySecondClass object = new MySecondClass();
object.doSomething();
}
}
Whats the difference between this code and code in constructor? This code executes before the object creation.
The code inside the braces with no names will be part of the constructor of the class and be executed before the logic contained in the class constructor.
Quick example:
public class Foo {
{
System.out.println("Before Foo()");
}
public Foo() {
System.out.println("Inside Foo()");
}
{
System.out.println("Not After Foo()");
}
}
This is called an instance initializer. The code in the initializer is inserted after the call to the super class constructor and before the rest of the constructor code.
The first operation of any constructor is to invoke a super class constructor. If a constructor is called explicitly, super(...), the specified constructor is used. If no constructor is explicitly invoked, the default constructor (with no arguments) is invoked in the super class. If no such constructor exists, it is a compile time error.
After this explicit or implicit constructor invocation, instance initializers are invoked in the order they appear in source code (yes, you can have more than one initializer).
To illustrate, running this program prints
Another constructor
Init 1
Init 2
Test constructor
class Another {
Another() { System.out.println("Another constructor"); }
}
class Test extends Another {
public static void main(String[] args) { new Test(); }
{ System.out.println("Init 1"); }
Test() { System.out.println("Test constructor"); }
{ System.out.println("Init 2"); }
}
The most commonly seen application is in the initalization the "double brace initialization" idiom, where an anonymous inner class is defined, and an instance is created and configured at once. Here's a fairly common example from Swing programming:
JButton popupButton = new JButton(new AbstractAction("Popup") {
{
putValue(Action.SHORT_DESCRIPTION, "Popup a dialog");
}
#Override
public void actionPerformed(ActionEvent evt)
{
popup();
}
});
This could be useful if you have multiple constructors, and need to perform some parameter-less initialization in every constructor. This could be factored into an initialization block.
This is an instance initialization block that runs before the constructor and if you ask why would one wanna use it in place of the constructor? The answer is no, you don't.
Just wondering about the reason of compiling code like this:
You usually use it to factor out common code when using constructor overloading. So, the "the" above actually refers to one of the overloaded constructors that gets called on object instantiation after the common instance initialization code block has executed.
By the way, you could sometimes achieve the same by calling one constructor from the other but the call then has to be on the first line inside the calling constructor or the code won't compile.

calling hierarchy in constructors of super and base class

class a
{
a(){System.out.println("A");}
}
class b extends a
{
b()
{
super();
System.out.println("B");}
}
class c extends b
{
c(){System.out.println("c");}
}
class last
{
public static void main(String aaa[])
{
c obj = new c();
}
}
Output Comes as:
A
B
C
Shouldn't it be:
A
A
B
C
because of super keyword
super(); is always there if you don't specify explicitly. Java only adds automatic call if you don't specify it explicitly.
So your code
B() {
super();
System.out.println("B");
}
is same as
B() {
System.out.println("B");
}
No. If you have a call to super within the constructor, the automatic call doesn't get added. The compiler only adds the automatic call if you leave yours out. So the super(); line in b is unnecessary, as that's exactly what the compiler will add for you (a call to the default constructor). That is, these two bits of source result in identical bytecode:
// This
class b {
b() {
}
}
// Results in the same bytecode as this
class b {
b() {
super();
}
}
The reason for being able to call the superclass constructor directly is for passing arguments to it, since the compiler will only ever add calls to the default constructor (and will complain if there isn't one on the superclass).
super(); is called once within any constructor through inheritance tree, either you do it explicitly or it is done implicitly. So you shouldn't expect that "A" will be printed twice.
This won't compile:
b()
{
super();
super();
System.out.println("B");
}
Error message: Constructor must be the first statement in a constructor.
It means that you are not allowed to call super() multiple times in a constructor.
If you create sub class of some other class, with extends keyword, then java compiler puts super() call as first line of your constructor (in case you have not done that yourself).
In your example, the class a extends (by default) java.lang.Object() and after compilation the first line is call super() which calls Object default constructor.
SO before code in sub class constructor is ran, the code in its super class constructor is ran.
Why is A not printed multiple times? Because Java compiler adds super() in the beginning of constructor only if you have not done that yourself. (For example, you might want to call super class constructor that takes in some parameters)
Hopefully that clarifies things a little bit.
package threaddemo;
public class NewClass {
NewClass() {
System.out.println("hello");
}
}
class Child extends NewClass {
Child() {
System.out.println("child");
}
public static void main(String []ar) {
Child c1=new Child();
}
}

Constructor usages in Java

Can anybody explain the differences between these constructors. See this;
public MyClass() {
}
and
public MyClass() {
this();
}
and
public MyClass() {
super();
}
Second is not allowed to be declared in java because you are making recursive call to default constructor only. Also by default constructor has always super() method which is inserted by compiler if not specified explicitly.
public MyClass() { }
declares an empty no-arg constructor. If you declare no constructor for a class, the compiler effectively inserts this conrtsuctor for the class.
public MyClass() { this(); }
will not compile.
public MyClass() { super(); }
is a constructor which invokes the default constructor of the super-class. This will compile only if the super-class has a default constructor, or no constructor (in which case, the compiler inserts a default constructor anyways, as mentioned above). Also, leaving out the super(); call has the same effect.
I think that in the second case you probably meant to write:
public MyClass() {
super(); // not "this();"
}
Either way, your second case is a compilation error. The JLS says this:
"It is a compile-time error for a constructor to directly or indirectly invoke itself through a series of one or more explicit constructor invocations involving this." JLS 8.8.7
In your example, this() is an explicit constructor invocation that directly invokes the same constructor.
Finally, there is no semantic difference between the first and third forms. The first form has an implicit invocation of the no-args constructor of the superclass, and the third for just makes that invocation explicit.
Some people prefer to write the form with an explicit invocation for the sake of readability, but IMO it doesn't really make any difference.
It is very simple
Let me make you understand
first
public MyClass() { }
is simply a default public constructor
But when you write this
public MyClass() { this(); }
that means you are applying constructor chaining. Constructor Chaining is simply calling another constructor of the same class. This must be the first statement of the Constructor. But in your scenario you are passing nothing in this(); that means you are again calling the same constructor which will result in infinite loop. your class may have another constructor like this
public MyClass(int a) { }
then you may have called this
public MyClass(){ this(10); }
the above statement will make you to jump to the constructor receiving the same arguments that you have passed
Now,
public Myclass(){ super(); }
signifies that you are calling the constructor of the super class which is inherited by the class MyClass. the same scenario occurs here, you have passed nothing in the super(); which will call the default constructor of the Super class.
Lets look at the three type of constructor calls one by one.Each one has special purpose associated with them. But the concept is simple and very interesting to explore.
Case 1 :- This is default constructor with no arguments
public class MyClass{
public MyClass(){
}
}
The compiler will automatically supply a no-argument constructor for you if you do not write one.Thus if you write public class MyClass{ } .
This is equivalent to writing
public class MyClass{
MyClass(){ }
}
Points to be noted :-
Compiler automatically provide "super" when you do not use super "as the first line of the constructor". NOTE:- For "super" and "this" when you use in constructors always write them in the first line of your constructor code otherwise compiler will give error.
Even when you do not extend MyClass here compiler will give call to constructor to super Object class which is the root class of every class you create.
Case 2:- The use of "this".
Constructors use "this" to refer to another constructor in the same class with a different parameter list.
public MyClass() {
this();
}
So the above code will give compilation error "Recursive Constructor Invocation" as it is calling the same constructor and will end up in an infinite loop. To make this work you can instead write
public MyClass(String str){
System.out.println("constructor with arg "+ str);
}
public MyClass(){
this("Cons"); // note that "this" has to be at first line otherwise compiler gives error
System.out.println("constructor with no arg");
}
Here you can see the importance of "this" in constructors. It is used to call constructors from another constructor in the same function.
Case 3:- Use of "Super". Super is used to make a call to no-arg constructor of super call. Rest information is mentioned in Case 1 already.
public MyClass() {
super();
}
In the first case the constructor will insert a silent call to no argument constructor of the super-class which I guess in this case will be the Object class. In the second case the this() call will call the no argument constructor of class. It can sometimes cause an error too.
The first is the default empty constructor. It simply does nothing. If you don't have other constructors (with arguments), you don't have to define this sort of constructor at all. It is implicitly made default if no constructors are defined.
The second calls itself which causes a recursive loop, hence is forbidden.
The third calls the default no-args constructor of the super class but does nothing more. The super class is the one that your class extends from, or Object (implicitly extended if you don't specify the extends keyword).
From within a constructor, you can also use the this keyword to call another constructor in the same class. Doing so is called an explicit constructor invocation
http://docs.oracle.com/javase/tutorial/java/javaOO/thiskey.html
public class Rectangle {
private int x, y;
private int width, height;
public Rectangle() {
this(0, 0, 0, 0);
}
public Rectangle(int width, int height) {
this(0, 0, width, height);
}
public Rectangle(int x, int y, int width, int height) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
}
}
But second one leads to recursive constructor invocation and not allowed.
public MyClass() { }
--> this is normal constructor also called default constructor.
public MyClass() {
this();
}
--> You are making constructor recursive. Don't use this way. Well you can make use of this() like :
public MyClass() {
this(1); // always intitalize to 1
}
public MyClass(int i) {
this.i=i;
}
The second one will surely cause an OutOfMemoryError exception due to a stack overflow not compile due to a Recursive constructor invocation error as you're calling the same constructor from itself. Did you mean to write
super();
? In that case both forms are identical.
public MyClass() {
}
Will call the default no-args constructor of the base class implicitly, if it exists.
this() will be used to call MyClass() No-Args Constructor.
Though it will give Recurssion constructor error during Compilation
Eg:
public MyClass{
public MyClass(){
this(5); // Here this(5) will be used to call the MyClass Constructor with
// int value as Parameter
}
public MyClass(int i){
}
}
default constructor doing nothing special. each class in java has it per default until you write your own constructor, then you have to define it by your own again
public A() {}
public A(int value) {}
is the default constructor with a recursive call on it (invalid and shouldnt be used). with this() you call default constructor. for example with this(5) you call a defined constructor which takes an int value as parameter like the example from 1.
public A() { this(5); }
public A(int value) {}
default constructor which calls the default constructor from your super class
abstract class A {
public A() {}
}
class B extends A {
public B() {
/* calls A() */
super();
}

Any way to _not_ call superclass constructor in Java?

If I have a class:
class A {
public A() { }
}
and another
class B extends A {
public B() { }
}
is there any way to get B.B() not to call A.A()?
There is absolutely no way to do this in Java; it would break the language specification.
JLS 12 Execution / 12.5 Creation of New Class Instances
Just before a reference to the newly created object is returned as the result, the indicated constructor is processed to initialize the new object using the following procedure:
Assign the arguments for the constructor [...]
If this constructor begins with an explicit constructor invocation of another constructor in the same class (using this), then [...]
This constructor does not begin with an explicit constructor invocation of another constructor in the same class (using this). If this constructor is for a class other than Object, then this constructor will begin with an explicit or implicit invocation of a superclass constructor (using super).
Execute the instance initializers and instance variable initializers for this class [...]
Execute the rest of the body of this constructor [...]
The closest you can achieve to the desired behaviour is to delegate initialisation normally performed in the constructor to a template method, which you then override in your subclass implementation. For example:
public class A {
protected Writer writer;
public A() {
init();
}
protected void init() {
writer = new FileWriter(new File("foo.txt"));
}
}
public class B extends A {
protected void init() {
writer = new PaperbackWriter();
}
}
However, as other people have noted this can typically indicate a problem with your design and I typically prefer the composition approach in this scenario; for example in the above code you could define the constructor to accept a Writer implementation as a parameter.
Java deserialisation doesn't call the constructor, but it seems that it is based on some internal JVM tricks.
However, there is a framework that allows you to do that in a portable manner: Objenesis (http://www.theserverside.com/discussions/thread/44297.html)
I've seen this recently in Spring, when using CGLIB proxies, Spring creates two class instances, but the constructor is called only once: https://stackoverflow.com/a/11583641/2557118
This behavior is added in Spring 4:
CGLIB-based proxy classes no longer require a default constructor.
Support is provided via the objenesis library which is repackaged
inline and distributed as part of the Spring Framework. With this
strategy, no constructor at all is being invoked for proxy instances
anymore.
The possibility is that you can call the super class constructor of your choice. That is possible by calling the super class constructor explicitly as :
super(para_1, para_2,........);
class BaseA {
BaseA(){
System.out.println("This is BaseA");
}
BaseA(int a){
System.out.println("This is BaseA a");
}
}
class A extends BaseA {
A(){
super(5);
System.out.println("This is A");
}
public static void main(String[] args) {
A obj=new A();
}
}
Output will be:
This is BaseA a
This is A
No and if you could, your derived object wouldn't really be the object it's deriving from now would it? The is-a principle would be violated. So if you really need it, then polymorphism isn't what you're after.
Every superclass needs to be constructed and there is no other way then calling a constructor.
I think the only way to do it is messing up with the byte-code.
I'm not sure if the Classloader or the JVM checks if super() is being called, but, as Bozho wrote, you probably would end with inconsistent objects when doing so.
Nope - you cannot do it and why would you want to do it anyway? That would mess up your object model.
Anyways - i believe if you still want to do it and then you would have to manipulate the generated byte code.... there are a couple of libraries available that make it easy to instrument the byte code.
Strongly suggest against doing it...
Every object in java is a subclass of Object (object with a capital 'O'). when you create an object of a subclass the super class constructor is invoked. Even if your class is not inhereting anyother class, implicitly it is inheriting Object, so the Object constructor has to be called. So super() is invoked for this purpose.
Assuming you mean
class B extends A {
public B() { }
}
then sure you can
class B extends A {
public B() {
this(abort());
}
private B(Void dummy) {
/* super(); */
}
private static Void abort() {
throw null;
}
}
Not very useful. The interface [not Java keyword] to class A says that you need to run its constructor in order to construct it, not unreasonably. The exception is that serialisable classes are constructed without calling the constructors of the serialisable classes.
As pointed out by another poster, B doesn't extend A, so it won't call A's constructor anyways.
There is no way to do this in Java.
You can probably accomplish equivalently what you want to do as follows:
a) in each class of your hierarchy, include a constructor with a unique signature that calls the superclass's constructor with its arguments. For example, declare a class "Noop" and a constructor that takes that as an argument:
public class NoOp {
}
public class class1 {
class1() {
System.out.println("class1() called");
}
class1(String x, String y) {
System.out.println("class1(String, String) called");
}
class1(NoOp x) {
System.out.println("class1(NoOp) called");
}
}
public class class2 extends class1 {
class2() {
System.out.println("class2() called");
}
class2(String x, String y) {
System.out.println("class2(String, String) called");
}
class2(NoOp x) {
super(x);
System.out.println("class2(NoOp) called");
}
}
public class class3 extends class2 {
class3() {
System.out.println("class3() called");
}
class3(String x, String y) {
super(new NoOp());
System.out.println("class3(String, String) called");
}
class3(NoOp x) {
super(x);
System.out.println("class3(NoOp) called");
}
public static void main(String args[]) {
class3 x = new class3("hello", "world");
}
}
If you run this you will get the output
class1(NoOp) called
class2(NoOp) called
class3(String, String) called
So, effectively you have created a class3 constructor that only calls constructors that don't do anything.
I had a similar requirement where I needed my child class NOT to go through the super class' constructor, and I wanted the rest of the benefits of the super class. Since super class is also mine, here's what I did.
class SuperClass {
protected SuperClass() {
init();
}
// Added for classes (like ChildClassNew) who do not want the init to be invoked.
protected SuperClass(boolean doInit) {
if (doInit)
init();
}
//
}
class ChildClass1 extends SuperClass {
ChildClass1() {
// This calls default constructor of super class even without calling super() explicitly.
// ...
}
// ....
}
class ChildClass2 extends SuperClass {
ChildClass2() {
// This calls default constructor of super class even without calling super() explicitly.
// ...
}
// ....
}
class ChildClassNew extends SuperClass {
ChildClassNew() {
/*
* This is where I didn't want the super class' constructor to
* be invoked, because I didn't want the SuperClass' init() to be invoked.
* So I added overloaded the SuperClass' constructor where it diesn;t call init().
* And call the overloaded SuperClass' constructor from this new ChildClassNew.
*/
super(false);
//
// ...
}
// ....
}

Categories