I am confused as to the purpose of empty constructors, let me ellaborate:
if I have a class..
public class Test {
private int x;
private int a[];
private static int y;
public Test() {
a = new int[3];
}
}
I know that there exists an empty default constructor:
public Test() {
//or at least I think it exists
} //what is its purpose?
if I have a main method and code the following:
Test t1 = new Test();
Which constructor is called? or is the empty constructor overwritten by the one which instantiates a[]?
If I then instantiate 5 instances of Test, how many integer memory locations are allocated?
Sooo confused....
The empty constructor is inherited from the Object class, which is the superclass of all classes in Java. It merely allocates memory of the objects, but does not initialize anything.
So for every object it is possible to call new A(), even if public A() is not defined explicitly.
Sometimes you don't need to do extra job in the constructor, so you can just use the default one without bothering reimplementing it.
When a child class overwrites it, then the one called is the new one. It makes perfect sense, because when you bother overwriting a method, you want to be able to use it instead of the default one.
In your examples, the Test class contains 2 integers, and an array of 3 integers.
Each time you instantiate a new Test, you allocate space for two more integers and the array of three integers. This is why those are called instance variables: it means they belong to an instance. So each instance has its own.
If you do not define any constructor for your class then compiler will automatically add a default parameter-less constructor to your class definition so that objects can be created using new keyword. If you explicitly define a parameter-less constructor (the way you have done) yourself then compiler will not add anything from his side.
So in this line of code
Test t1 = new Test();
the constructor that you have defined explicitly will be called.
To answer your second question - Each instantiation of your class results in allocation of memory required to hold an array containing 3 integers. For 5 instances it will simply become 5 times.
i.e. 5 * 3 * memory occupied by one integer
Which constructor is called? or is the empty constructor overwritten by the one which instantiates a[]?
Since you have provided constructor for Test class, your constructor will be called. If you want to call super class constructor explicitly, change your code as
public Test() {
super();
a = new int[3];
}
From oracle documentation page on constructors
You don't have to provide any constructors for your class, but you must be careful when doing this. The compiler automatically provides a no-argument, default constructor for any class without constructors. This default constructor will call the no-argument constructor of the superclass. In this situation, the compiler will complain if the superclass doesn't have a no-argument constructor so you must verify that it does. If your class has no explicit superclass, then it has an implicit superclass of Object, which does have a no-argument constructor
If I then instantiate 5 instances of Test, how many integer memory locations are allocated?
JVM will allocate space for 1 integer for static variable ( int y, which is class or static variable)
JVM will allocate space for 1 integer for each Test instance for int x, which is instance variable
JVM will allocate space for 3 integers for each Test instance for int a[] array, which is instance variable
Total : Space for 5 + 5 + 15 (=25) integers
Related
I have read in many sources and books that constructor is used to initialise the fields when an object is created. I have also read that JVM provides a default constructor if I don't mention one. What is the purpose of a constructor if it is not required to initialise the fields like the one I have mentioned below?
I also understand that a constructor without parameter is required as
it is necessary during object creation when an argument is not passed
(when programmer-defined constructors with parameters exists).
Is it necessary for JVM to provide a constructor which is actually not required?
public class test {
int a;
public test() {
//this constructor is useless
}
public static void main(String[] args)
{
test ob= new test();
System.out.println(ob.a);
//this prints 0 which means a constructor is not required in intialising `a`
}
}
A constructor like test() makes sense if the programmer defines it since there could be other constructors which takes argument.
But why is it necessary for JVM to provide one when no constructor is declared by the programmer?
I have already tested and proved that initialising a field doesn't require constructor.
Also what does the default constructor look like?
The problem is that while you know the default constructor doesn't do anything in this example, in future the constructor might do something even if you don't realise it is and you might not be able to re-compile everywhere the code is used reliably. So the safest, simplest thing to do is to always call a constructor which might change in the future and let the JIT optimise away the constructor if it doesn't actually do anything.
The byte code always calls a contructor, whether you provide one or not. When you compile code which uses the default constructor it cannot assume the constructor doesn't do anything useful as you can add something to it later to do something useful. e.g.
Say you change
public class Test {
int a;
// public Test() { //this constructor does nothing
}
to
public class Test {
int a;
final List<String> strings = new ArrayList<>();
// public Test() { //this constructor does something now.
}
or
public class ServerTest {
final List<String> strings = new ArrayList<>();
}
public class Test extends SuperTest {
int a;
// the default constructor has to call super();
}
The constructor now initialised the strings field. You can change this class without having to re-compile everywhere it is used and say, hey, my constructor now does something useful, you should call it now.
The reason the JVM adds a default constructor if you haven't provided one is down to inheritance. Say for example you have 3 classes (A, B & C) in which B extends A and C extends B. Now when you instantiate C it will call the constructor of C and also the constructors of B and A. If a constructor was missing in one or more of these classes then the instantiation would fail. So having the compiler automatically add a default constructor avoids error like this. You may not need to actually do any work in your constructor, but it's required for the JVM to instantiate the object.
The constructor(s) (both default and custom one(s)) is not only used to initialize the fields of an object but also to initialize the object itself even if it has no fields at all. Calling the constructor, JVM allocates memory for this object and creates its reference.
It is the compiler, and not JVM, who inserts a default constructor on absence.
A default constructor is needed because the constructor of the base class needs to be called from a constructor.
The default constructor looks like:
public Test() {
super();
}
Here while you are creating the object new test(),
here parenthesis states the default constructor of object test.After creating the object,if you didnot give any constructor the default constructor is constructed by jvm.so after construction of your object first call goes to your default constructor.
The default constructor is a no argument constructor called automatically by the compiler when you haven't defined any constructor. Anyway, a constructor as the one you defined, can be also called a default constructor.
It basically calls the superclass' constructor making use of the super() method.
So the default constructor called automatically would be something like:
public ClassName(){
super();
}
Java's Compiler creates a Default Constructor if no other constructor is defined for the class.
But why?
The compiler's job is to chain the Subclass's constructor to the Super Class(ultimately Object class). It's not the Compiler's work to give a default constructor to your class therefore Java is doing it for you.
To do the chaining, it first checks if there is any constructor in the class, if yes it will add super() to that constructor.
If there is no constructor idefined in the class in order for the compiler to do a proper chaining, Java adds a default constructor and a call to super() into it.
Why ?
Because every class is a subclass of an Object class (directly or indirectly), it will inherit an object class, to do so the said Object class must be fully initialised. This is done by the default constructor.
Java - I mean do instances share same instance method in memory?For example:
public class Test {
private int a;
private int b;
public Test(int a , int b){
this.a = a;
this.b = b;
}
/* instance method - sum() */
public int sum(){
return a+b;
}
public static void man(String[] args) {
Test t1 = new Test(3,4);
Test t2 = new Test(5,6);
t1.sum();
t2.sum();
}
}
I know when apply new keyword to a class, class variables (properties) will be copied. So instances can have their own property values separately.
But how about method? will it also make a copy? If so, just waste memory resources, because the methods are always same.
what happended in JVM when using a new keyword ? thanks very much!
NOTE: official doc reference is highly preferred :)
But how about method? will it also make a copy? If so, just waste
memory resources, because the methods are always same.
No, there will always be a single copy of each method (in the method area of the JVM). This applies for both static and non-static methods.
Are there some kindly people tell me what happended in JVM when using
a new keyword ? thanks very much!
Simply put, a new Object is created in the heap space by calling the appropriate constructor. A reference to that object is returned.
Methods of a class is stored on stack in .class instance which stores all methods of a class. Only one copy is created for method and it is invoked by all instance of the class.JVM keeps reference of all methods defined in a class and linked it with instance when it calls a method.
what happended in JVM when using a new keyword ?
When we simply put 'new' keyword it creates an object on the heap.
All instances share the same code.
If you compile your Java class and create an instance inside of another class of it, they will call the function on the same Java class (.class)-File.
Of course virtual calls make things somewhat more complex, but basically instance method is like a static method with additional implicit this parameter. Calling t1.sum() is like calling sum(t1) (with additional null check for t1). No reason to duplicate the method for every possible parameter value.
Is there any difference between these two ways of initialising class members?
In the class body:
public class A {
private mB = new B();
public A() {
}
}
Or in the constructor:
public class A {
private mB = null;
public A() {
mB = new B();
}
}
In theory, there is a difference in the sequence of initialization. This is the sequence used by the JVM:
Static statements/static blocks are executed.
Instance variables are assigned default values
Instance variables are initialized if the instance variable is assigned a compile time constant. Otherwise, it will be done with Item 5 (instance variables and instance initializers will be done together from the top to the bottom, in the order they are defined).
constructor runs
Instance initialization block(s) run after all the call(s) to super has(have) been completed but before the rest of the constructor is executed.
Rest of the constructor is executed.
Also, if you initialize the fields in the constructor, it can mean that you might get some duplication. Personally, I think it doesn't matter much where you instantiate them, either in the constructor or in the fields, but the main point is that you are consistent about it. For me it helps having them instantiated in the field declaration so I know which fields are always there, and which fields are optional. Hope that helps!
The instance initializer run first and then values in constructor are initialized. You can study order of execution of initialization blocks and constructors
If B() constructor threw a checked exception then this
private mB = new B();
would be a compile time error, while in constructor you could catch it or declare in throws clause
I would do the one you believe is simpler.
The main difference is that if you add another constructor to the first, you don't have to repeat the initialisation.
Your first example initializes the variable once: your second example, twice. First is to be preferred, especially if there are multiple constructors, unless there is an exception involved of course.
As per standard book constructor is a special type of function which is used to initialize objects.As constructor is defined as a function and inside class function can have only two type either static or non static.My doubt is what constructor is ?
1.)As constructor is called without object so it must be static
Test test =new Test();//Test() is being called without object
so must be static
My doubt is if constructor is static method then how can we frequently used this inside
constructor
Test(){
System.out.println(this);
}
Does the output Test#12aw212 mean constructors are non-static?
Your second example hits the spot. this reference is available in the constructor, which means constructor is executed against some object - the one that is currently being created.
In principle when you create a new object (by using new operator), JVM will allocate some memory for it and then call a constructor on that newly created object. Also JVM makes sure that no other method is called before the constructor (that's what makes it special).
Actually, on machine level, constructor is a function with one special, implicit this parameter. This special parameter (passed by the runtime) makes the difference between object and static methods. In other words:
foo.bar(42);
is translated to:
bar(foo, 42);
where first parameter is named this. On the other hand static methods are called as-is:
Foo.bar(42);
translates to:
bar(42);
Foo here is just a namespace existing barely in the source code.
Constructors are non-static. Every method first parameter is implicit this (except static) and constructor is one of that.
Constructors are NOT static functions. When you do Test test =new Test(); a new Test object is created and then the constructor is called on that object (I mean this points to the newly created object).
The new keyword here is the trick. You're correct in noting that in general, if you're calling it without an object, a method is static. However in this special case (i.e., preceded by the new keyword) the compiler knows to call the constructor.
The new operator returns a reference to the object it created.
new Test(); // creates an instance.
The System.out.println(this); is called after the new operator has instantiated the object
Not static. Read about constructors http://www.javaworld.com/jw-10-2000/jw-1013-constructors.html.
Neither.
Methods can be divided into 2 types: static/non-static methods, aka class/instance methods.
But constructors are not methods.
When we talk about static class then it comes to our mind that methods are called with class name,But in case of constructor ,Constructor is initialized when object is created So this proves to be non-static.
Constructors are neither static (as called using class name) or non-static as executed while creating an object.
Static:
Temp t= new Temp();
The new operator creates memory in the heap area and passes it to the constructor as Temp(this) implicitly. It then initializes a non-static instance variable defined in a class called this to the local parameter variable this.
Below example is just for understanding the concept, if someone tries to compile it, it will give the compile-time error.
class Temp{
int a;
Temp this; //inserted by compiler.
Temp(Temp this){ //passed by compiler
this.this=this; // initialise this instance variable here.
this.a=10;//when we write only a=10; and all the non-static member access by this implicitly.
return this; // so that we can't return any value from constructor.
}
}
Constructor is static because:
It is helping to create object.
It is called without object.
Constructor is used to initialize the object and has the behavior of non-static methods,as non-static methods belong to objects so as constructor also and its invoked by the JVM to initialize the objects with the reference of object,created by new operator
When does the Constructor get called?
Before object creation.
During object creation.
After object creation.
The object memory is allocated, the field variables with initial values are initialized, and then the constructor is called, but its code is executed after the constructor code of the object super class.
At the byte code level.
An object is created but not initialised.
The constructor is called, passing the object as this
The object is fully constructed/created when the constructor returns.
Note: The constructor at the byte code level includes the initial values for variables and the code in the Java constructor.
e.g.
int a = -1;
int b;
Constructor() {
super();
b = 2;
}
is the same as
int a;
int b;
Constructor() {
super();
a = -1;
b = 2;
}
Also note: the super() is always called before any part of the class is initialised.
On some JVMs you can create an object without initialising it with Unsafe.allocateInstance(). If you create the object this way, you can't call a constructor (without using JNI) but you can use reflections to initialise each field.
It gets called at object creation. The memory must be reserved first for the object, otherwise the constructor code could not run. So maybe we could say after object creation. Also note that initialization code written in the class gets called before the constructor code.
public Ex {
int xVal = -1;
int yVal;
public Ex() {
// xVal is already -1.
//yVal defaults to 0.
}
}
THE JVM will first allocate the memory for your object, then initialize all fields, then invoke your constructor.
The constructor gets called when a new object is created.
NewObject n = new NewObject();
public class NewObject {
public NewObject() {
// do stuff when object created
}
}
Hope this helps.
basically constructors are called to initialize the values of the instance variables except the case for default constructors. However, this initialization of the instance variables are done in 4 steps (as applicable):
variables are initialized with default values (ints with 0, chars with u\0000 etc.)
variables are initialized with explicit initialization values
initialized with static blocks
constructors are called
After the Object creation
once an object is created using new operator like Student s = new Student();
first Student object is created, and then constructor is called to initialize the variable of the object
We can prove constructor is called after creating the object by using below code
here we are using instance block. And also instance block is executed before the constructor
so I am printing hash code in three places
Inside Instance block
Inside Constructor
Inside main mehtod
all these three times hash code is equal, that means object is created before the constructor is executed
because having a hash code means, there must be an object. And if hash code printed inside both instance block and constructor is equal. that means object must be created before the constructor execution
Constructor is what practically creates object. It is called when object is created by executing new MyClass() (or its parametrized version).
Given those options, 1. Before object creation.
After the constructor finishes, the object has been created.
Whenever we create an object by using 'new' operator then 1st task is performed by the new i.e. it allocates the memory for object in heap with pointing to the reference variable in stack and set the initial values of object fields.then it calls the constructor with passing 'this' as object to initialize it according to your requirement...
So the constructor is always called after the object creation....
Note: When you enter in constructor so 'this' keyword is working means your object has been created.