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();
}
}
Related
In the book Java: The complete reference
// Demonstrate when constructors are called.
// Create a super class.
class A {
A() {
System.out.println("Inside A's constructor.");
}
}
// Create a subclass by extending class A.
class B extends A {
B() {
System.out.println("Inside B's constructor.");
}
}
// Create another subclass by extending B.
class C extends B {
C() {
System.out.println("Inside C's constructor.");
}
}
class CallingCons {
public static void main(String args[]) {
C c = new C();
}
}
Output:
Inside A’s constructor
Inside B’s constructor
Inside C’s constructor
It is demonstrating how the constructor of a subclass is called. But why are constructors of the super class called in the absence of a super() constructor.
Why did the Java Language designers consider it necessary to do so?
As others have pointed out, if you don't start your constructor with a super(...) call, the compiler will put in a call to super() for you.
As to the why, you have to start with remembering what a constructor is for in the first place: initializing the object. What does that mean, specifically? In practice, it means assigning values to the object's fields, and establishing invariants.
Without a call to super(), the B and A classes wouldn't have a chance to do that for whatever fields they contain. And you can't even have the C() constructor do it for them, if those fields are private, since private fields aren't accessible outside your class (not even your super class's fields are accessible). Even if you could, it wouldn't be a good idea; it would also break encapsulation. For instance, imagine having to change your code if a super class -- possibly a complex one whose internals you're not an expert in -- suddenly decided to change its implementation details.
To illustrate this, consider a very simple set of classes:
public class Super {
private final String name;
Super() {
name = "default";
}
public String name() {
return name.toUpperCase();
}
}
public class Sub extends Super {
public Sub() {
// don't do anything
}
}
When you instantiate Sub, it will start out by calling Super's constructor. If it didn't, the name field would be null (the default value for reference types). But the name() method doesn't check for null; it assumes that the reference is non-null, because the constructor establishes that invariant. So, in our pseudo-Java that doesn't call the super constructor, Super.name has to get a bit more complicated -- it has to check for name == null.
You can imagine that as the classes gain more fields, with more interesting invariants, this toy example can become more and more complicated. Forcing you to call the super constructor -- either explicitly or implicitly -- lets the authors of that super class establish their invariants, resulting in simpler, more maintainable code.
Every constructor calls its superclass constructor. super() call take place as the first line in the constructor. From javadoc:
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.
more here
Because it says so in the Java Language Specification.
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.
Even it has a role with Abstract classes also. we can't initialize object of abstract class. But Child class of Abstract class calls the super() method by default. So abstract class constructor can initialize its instance variables.
for example:
public abstract class TestA {
private int a;
public TestA()
{
a=10;
}
public int displayA()
{
return a;
}
abstract void display();
}
public class TestB extends TestA{
#Override
void display() {
System.out.println("this is class B");
}
}
package Abstract;
public class TestMain {
public static void main(String[] args) {
TestA obj= new TestB();
System.out.println(obj.displayA());
}
}
Output is : 10
Here you can see, when we initiating object of class TestB , by default super constructor is calling and TestA's constructor is assigning the value of a. If super will not be called by default we can't assign instance variables of abstract class.
Inheritance is basically inheriting all the properties of your parent class. So if a sub class constructor is called, it should definitely and by default inherit all its parent class properties also. In the following code, all the properties of class A should be made available in class B also, so if I just call B's constructor, all the class A's properties(except private) are also initialized and made available, meaning B has inherited A's properties
class A {
protected int a;
A() {
a=12;
System.out.println("Inside A's constructor.");
}
}
class B extends A {
B() {
System.out.println("Inside B's constructor.");
System.out.println(a);
}
}
public class ConstructorInheritance {
public static void main(String args[]) {
B b=new B();
}
}
output:
Inside A's constructor.
Inside B's constructor.
12
Imagine class C accessing an unitialized variable of class B or A. Implicitly calling constructors of class B-->class A makes sure that you are always accessing initialized variables of inherited classes(A or B)
"The Java programming language" says "A constructor in subclass can initialize its individual state, however, as keeping contract, only super class knows how to initialize super class's state".
Thus, constructor of super class have to be called. There is sequence how the constructor processed:
Call super class constructor
Initialize fields with initializers and initialization blocks
Execute body of the constructor
For more details, have a look of the book to section "3.2".
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.
I'm having trouble understanding the concept of using constructors with subclasses.
Here is the parent class:
public class A
{
public A()
{
System.out.println("The default constructor of A is invoked");
}
}
The child class:
public class B extends A
{
public B(String s)
{
System.out.println(s);
}
}
And my main method:
public class C
{
public static void main (String[] args)
{
B b = new B("The constructor of B is invoked");
}
}
When I run C, the output I get is
The default constructor of A is invoked
The constructor of B is invoked
What I don't understand is why the message from class A is getting output. Because you pass in a string argument to the constructor of the B class, shouldn't it just print out s? In other words, shouldn't the output simply be:
The constructor of B is invoked
Thanks in advance, I really appreciate any help you guys can give.
From the docs
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 even though you've not explicitly called the super class constructor, the compiler inserts a statement called super() in the constructor of class B.
This is how the class B constructor would look post compilation.
public B(String s){
super(); // this is inserted by the compiler, if you hadn't done it yourself.
System.out.println(s);
}
After compilation class B -
public class B extends A{
public B(String s){
super();
System.out.println(s);
}
}
And why! logical answer is child can not be existed without parent, so parent is initialized fast then child.
Technically - if you do not explicitly invoke super class constructor compiler will do it for you. what exactly happened in your case.
A good experiment would be if you invoke the super class contructor explicitly which help you understand this more closely-
public class B extends A{
public B(String s){
System.out.println(s);
super(); // invoking super later
}
}
you get an compilation error -
error: call to super must be first statement in constructor
So In case you are explicitly invoking the super class constructor, then you have to invoke at the start of constructor which should be first statement.
The reason it does this is that B needs to have all the fields in A if B is indeed a subclass of A. Therefore, when you call the constructor
B b = new B("The constructor of B is invoked");
It calls the default constructor of A to initialize A's fields, thus B is actually logically doing
public class B extends A
{
public B(String s)
{
super();
System.out.println(s);
}
}
where super just calls A's default constructor. If the compiler did not do this, you would have uninitialized fields in B since it inherits from A!
Why default constructor(same class) is not getting called while calling the default constructor but the default constructor of parent class is getting called - Why?
class A{
A(){
System.out.println("A()");
}
}
class B extends A{
B(){
System.out.println("B()");
}
}
class C extends B{
C(){
System.out.println("C()");
}
C(int i){
System.out.println("<------>"+i);
}
}
public class sample {
public static void main(String[] args) {
C c = new C(8);
}
}
Output:
A()
B()
<------>8
This is how the language works: only one constructor is called per class, unless you specifically invoke one constructor from another (like so: How do I call one constructor from another in Java?).
It's Java's rule. If you want your behaviour you must use this() as first instruction in C(int).
as said before it's standard behavior of java if you want some code to be always called on construction of an object you can use an initializer
class A{
{
System.out.println("A()");
}
A(){
}
}
Based on your class declaration for class 'C', you are overloading the constructors and thus when you create a new 'C' object and pass in an integer with the following code:
C c = new C(8);
You are calling the constructor
C(int i){
System.out.println("<------>"+i);
}
instead of the constructor
C(){
System.out.println("C()");
}
therefore it doesn't print out "C()". Overloading constructors/functions depends on the type and number of parameters being passed in. On top of that, only 1 constructor gets called for each object being created.
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);
//
// ...
}
// ....
}