This question already has answers here:
Java order of Initialization and Instantiation
(2 answers)
java "void" and "non void" constructor
(5 answers)
Closed 3 years ago.
I'm trying to understand the call sequence for my code. Someone, please explain the call sequence.
public class MainWithStaticCalls
{
static
{
String[] str = {"1", "2"};
System.out.println("Static");
main(str);
}
{
System.out.println("Init block");
}
void MainWithStaticCalls()
{
System.out.println("constructor");
}
public static void main(String[] a)
{
MainWithStaticCalls obj = new MainWithStaticCalls();
NewClass nc = new NewClass();
nc.callMe();
System.out.println("Main");
}
}
class NewClass
{
public void callMe()
{
System.out.println("I'm called");
}
}
As per my understanding, the static block will get executed as soon as the JVM starts its execution, even before main class. and instance init block gets executed after that. then constructor should get executed. But how the call back works if we call the main method from the static field. and which main will gets executed first, the one which JVM executes normally or the one which static field has called explicitly.
My output:
Static
Init block
I'm called
Main
Init block
I'm called
Main
P.S: I have modified my question. Earlier I confused the normal method with a Constructor so a few answers may look irrelevant, but that indeed helped me in understanding the problem.
I'll try to explain the calling sequence with an example, but first of all let's consider that if you add the void access qualifier, this will be a method and not a constructor.
Secondly remember that a class can have two type of initialization block:
Static Initialization Block
Instance Initialization Block
The Static Initialization Block will be called first of all and before the constructor, since is at class level and will be execute even before any class instance (i.e. object of that class type) is created. The second, i.e. the Instance Initialization Block is executed as soon as a new instance of the class is created. After that two blocks, it will be called the constructor. You can see it with the following example:
public class MainWithStaticCalls {
{
System.out.println("Init block called");
}
static {
String[] str = {"1", "2"};
System.out.println("Static called");
}
public MainWithStaticCalls() {
System.out.println("this is constructor");
}
void MainWithStaticCalls() {
System.out.println("this is NOT constructor");
}
public static void nope() {
System.out.println("Nope");
}
public static void main(String[] a) {
MainWithStaticCalls.nope();
System.out.println("************");
MainWithStaticCalls obj = new MainWithStaticCalls();
NewClass nc = new NewClass();
nc.callMe();
System.out.println("Main");
}
}
The output is:
Static called
************
Init block called
this is constructor
NewClass: I'm called
Main
If I comment out the "nope" static call:
public class MainWithStaticCalls {
... // Same thing as above
public static void main(String[] a) {
// MainWithStaticCalls.nope();
System.out.println("************");
MainWithStaticCalls obj = new MainWithStaticCalls();
NewClass nc = new NewClass();
nc.callMe();
System.out.println("Main");
}
}
The result is:
Static called
************
Init block called
this is constructor
NewClass: I'm called
Main
So it is the same result if do not comment out the "nope" call. This is to show that the static method is called only once, when the class is firstly faced by the JVM. If we instantiate another object:
public class MainWithStaticCalls {
... // Same thing as above
public static void main(String[] a) {
// MainWithStaticCalls.nope();
System.out.println("************");
MainWithStaticCalls obj1 = new MainWithStaticCalls();
MainWithStaticCalls obj2 = new MainWithStaticCalls();
NewClass nc = new NewClass();
nc.callMe();
System.out.println("Main");
}
}
The output is:
Static called
************
Init block called
this is constructor
Init block called
this is constructor
NewClass: I'm called
Main
you see that the Instance Initialization Block is called every time a new object fof that class type is created (as well as the constructor), while the Static Initialization Block is called only once.
There is no constructor defined in class, so default constructor gets called.
void MainWithStaticCalls()
is not a constructor. This is method, as constructor don't have return type.
void MainWithStaticCalls() is a method not a constructor.
Change it to,
public MainWithStaticCalls()
{
System.out.println("constructor");
}
There are rules defined for the constructor.
Constructor name must be the same as its class name
A Constructor must have no explicit return type
A Java constructor cannot be abstract, static, final, and synchronized
In Java, the constructor is not a method. It only has the name of the class and a specific visibility. If it declares that returns something, then it is not a constructor, not even if it declares that returns a void.
As others have already mentioned you confused constructor with method. Remove 'void' to make it a constructor again. Just for reference - this is how constructor described in the oracle docs: https://docs.oracle.com/javase/tutorial/java/javaOO/constructors.html
Related
This question already has answers here:
"Non-static variable this cannot be referenced from a static context" when creating an object
(5 answers)
Closed last year.
import java.util.*;
public class MyClass {
MyClass()
{
}
public static void main(String args[]) {
Node n = new Node();// CT error - non-static variable this cannot be referenced from a static context
MyClass obj = new MyClass();//works (Why? Since this is also a non-static)
test t = new test();//works (Why? Since this is also a non-static)
}
class Node{
};
}
class test{
}
How can main method (which is static) call it's own class' constructor even if it is non-static? And can't call nested class' constructor.
It's important to note the distinction between calling a static method, which you can do whenever, and calling a non-static method, which must be done on an instance.
class Foo {
public void run() {
System.out.println("Hello, world!");
}
public static void static_run() {
Foo f = new Foo();
f.run();
}
public static void main(String[] args) {
Foo.static_run(); // Calling a static method from a static context
(new Foo()).run(); // Calling a non-static method on an instance of Foo
Foo.run(); // Error! Cannot call a non-static method from a static context
A a = new Foo.A(); // This is fine since A is a static class
B b1 = new Foo.B(); // Error! B is non-static but is being called from a static context
B b2 = new (new Foo()).B(); // This is fine since B is created on an instance of Foo, not from a static context
C c = new C(); // This is fine since top-level classes are implicitly static (i.e. they must be static)
}
static class A {}
class B {}
}
class C {}
Notice how we can create instances of our class within it's own static methods.
I wrote this simple class in java just for testing some of its features.
public class class1 {
public static Integer value=0;
public class1() {
da();
}
public int da() {
class1.value=class1.value+1;
return 5;
}
public static void main(String[] args) {
class1 h = new class1();
class1 h2 = new class1();
System.out.println(class1.value);
}
}
The output is:
2
But in this code:
public class class1 {
public static Integer value=0;
public void class1() {
da();
}
public int da() {
class1.value=class1.value+1;
return 5;
}
public static void main(String[] args) {
class1 h = new class1();
class1 h2 = new class1();
System.out.println(class1.value);
}
}
The output of this code is:
0
So why doesn't, when I use void in the constructor method declaration, the static field of the class doesn't change any more?
In Java, the constructor is not a method. It only has the name of the class and a specific visibility. If it declares that returns something, then it is not a constructor, not even if it declares that returns a void. Note the difference here:
public class SomeClass {
public SomeClass() {
//constructor
}
public void SomeClass() {
//a method, NOT a constructor
}
}
Also, if a class doesn't define a constructor, then the compiler will automatically add a default constructor for you.
public void class1() is not a constructor, it is a void method whose name happens to match the class name. It is never called. Instead java creates a default constructor (since you have not created one), which does nothing.
Using void in the constructor by definition leads it to not longer be the constructor.
The constructor specifically has no return type. While void doesn't return a value in the strictest sense of the word, it is still considered a return type.
In the second example (where you use the void), you would have to do h.class1() for the method to get called because it is no longer the constructor. Or you could just remove the void.
This is arguably a design flaw in Java.
class MyClass {
// this is a constructor
MyClass() {...}
// this is an instance method
void MyClass() {...}
}
Perfectly legal. Probably shouldn't be, but is.
In your example, class1() is never getting called, because it's not a constructor. Instead, the default constructor is getting called.
Suggestion: familiarize yourself with Java naming conventions. Class names should start with uppercase.
The reason the constructor doesn't return a value is because it's not called directly by your code, it's called by the memory allocation and object initialization code in the run time.
Here is an article explaining this in greater detail:
https://www.quora.com/Why-is-the-return-type-of-constructor-not-void-while-the-return-type-of-a-function-can-be-void
I'm learning about inheritance and am working with this simple program that has has a superclass and a subclass as shown below. My question isn't specific to this program; however, this is where I've first seen this happen so I'm using it as an example for a more general conceptual question. Why does simply instantiating the class run the constructors and output the contents? My previous understanding was that instantiating the class simply creates the object but it wont do anything.
SuperClass1.java
public class SuperClass1 {
public SuperClass1(){
System.out.println("This is the superclass constructor.");
}
}
SubClass2.java
public class SubClass2 extends SuperClass1
{
public SubClass2()
{
System.out.println("This is the subclass constructor.");
}
}
Main.java
public class Main {
public static void main(String[] args)
{
SubClass2 obj1 = new SubClass2(); // why should this print something?
}
}
Output
This is the superclass constructor.
This is the subclass constructor.
First of all, instantiating an object means calling (and executing) the constructor, that is what it is for.
So, this:
SubClass2 newInstance = <createNewInstance>;
newInstance.<init()>;
is both done by the constructor call new SubClass2() in Java. There is no separation between "constructing" the object and "initialising" its properties.
Furthermore, if you do not explicitly call another constructor of a super class the default constructor (the one without arguments) is automatically called first thing when creating an object of a class. So instantiating an object of the subclass calls the superclass contructor (which prints the first line), and then prints the second line itself.
More in detail, the subclass looks like this behind the scene:
public class SubClass2 extends SuperClass1
{
public SubClass2()
{
super(); // calls the superclass constructor
System.out.println("This is the subclass constructor.");
}
}
Because the constructor you call includes a print statement.
You call the constructor method SubClass2() which has a print statement in it.
The statements are not printed because the class ist loaded, but because an object of that class in instantiated and the constructors are called:
That a class can be loaded without using constructor is demonstrated by the following code:
public class Test {
public static void main(String[] args) {
try {
Class.forName("Test$Inner");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
static class Inner {
static {
System.out.println("static initializer");
}
public Inner() {
System.out.println("inner ctor");
}
}
}
running that program shows that only the static class initializer is called and no constructor.
We can put code in a constructor or a method or an initialization block. What is the use of initialization block? Is it necessary that every java program must have it?
First of all, there are two types of initialization blocks:
instance initialization blocks, and
static initialization blocks.
This code should illustrate the use of them and in which order they are executed:
public class Test {
static int staticVariable;
int nonStaticVariable;
// Static initialization block:
// Runs once (when the class is initialized)
static {
System.out.println("Static initalization.");
staticVariable = 5;
}
// Instance initialization block:
// Runs each time you instantiate an object
{
System.out.println("Instance initialization.");
nonStaticVariable = 7;
}
public Test() {
System.out.println("Constructor.");
}
public static void main(String[] args) {
new Test();
new Test();
}
}
Prints:
Static initalization.
Instance initialization.
Constructor.
Instance initialization.
Constructor.
Instance initialization blocks are useful if you want to have some code run regardless of which constructor is used or if you want to do some instance initialization for anonymous classes.
would like to add to #aioobe's answer
Order of execution:
static initialization blocks of super classes
static initialization blocks of the class
instance initialization blocks of super classes
constructors of super classes
instance initialization blocks of the class
constructor of the class.
A couple of additional points to keep in mind (point 1 is reiteration of #aioobe's answer):
The code in static initialization block will be executed at class load time (and yes, that means only once per class load), before any instances of the class are constructed and before any static methods are called.
The instance initialization block is actually copied by the Java compiler into every constructor the class has. So every time the code in instance initialization block is executed exactly before the code in constructor.
nice answer by aioobe
adding few more points
public class StaticTest extends parent {
static {
System.out.println("inside satic block");
}
StaticTest() {
System.out.println("inside constructor of child");
}
{
System.out.println("inside initialization block");
}
public static void main(String[] args) {
new StaticTest();
new StaticTest();
System.out.println("inside main");
}
}
class parent {
static {
System.out.println("inside parent Static block");
}
{
System.out.println("inside parent initialisation block");
}
parent() {
System.out.println("inside parent constructor");
}
}
this gives
inside parent Static block
inside satic block
inside parent initialisation block
inside parent constructor
inside initialization block
inside constructor of child
inside parent initialisation block
inside parent constructor
inside initialization block
inside constructor of child
inside main
its like stating the obvious but seems a little more clear.
The sample code, which is approved as an answer here is correct, but I disagree with it. It does not shows what is happening and I'm going to show you a good example to understand how actually the JVM works:
package test;
class A {
A() {
print();
}
void print() {
System.out.println("A");
}
}
class B extends A {
static int staticVariable2 = 123456;
static int staticVariable;
static
{
System.out.println(staticVariable2);
System.out.println("Static Initialization block");
staticVariable = Math.round(3.5f);
}
int instanceVariable;
{
System.out.println("Initialization block");
instanceVariable = Math.round(3.5f);
staticVariable = Math.round(3.5f);
}
B() {
System.out.println("Constructor");
}
public static void main(String[] args) {
A a = new B();
a.print();
System.out.println("main");
}
void print() {
System.out.println(instanceVariable);
}
static void somethingElse() {
System.out.println("Static method");
}
}
Before to start commenting on the source code, I'll give you a short explanation of static variables of a class:
First thing is that they are called class variables, they belong to the class not to particular instance of the class. All instances of the class share this static(class) variable. Each and every variable has a default value, depending on primitive or reference type. Another thing is when you reassign the static variable in some of the members of the class (initialization blocks, constructors, methods, properties) and doing so you are changing the value of the static variable not for particular instance, you are changing it for all instances. To conclude static part I will say that the static variables of a class are created not when you instantiate for first time the class, they are created when you define your class, they exist in JVM without the need of any instances. Therefor the correct access of static members from external class (class in which they are not defined) is by using the class name following by dot and then the static member, which you want to access (template: <CLASS_NAME>.<STATIC_VARIABLE_NAME>).
Now let's look at the code above:
The entry point is the main method - there are just three lines of code. I want to refer to the example which is currently approved. According to it the first thing which must be printed after printing "Static Initialization block" is "Initialization block" and here is my disagreement, the non-static initialization block is not called before the constructor, it is called before any initializations of the constructors of the class in which the initialization block is defined. The constructor of the class is the first thing involved when you create an object (instance of the class) and then when you enter the constructor the first part called is either implicit (default) super constructor or explicit super constructor or explicit call to another overloaded constructor (but at some point if there is a chain of overloaded constructors, the last one calls a super constructor, implicitly or explicitly).
There is polymorphic creation of an object, but before to enter the class B and its main method, the JVM initializes all class(static) variables, then goes through the static initialization blocks if any exist and then enters the class B and starts with the execution of the main method. It goes to the constructor of class B then immediately (implicitly) calls constructor of class A, using polymorphism the method(overridden method) called in the body of the constructor of class A is the one which is defined in class B and in this case the variable named instanceVariable is used before reinitialization. After closing the constructor of class B the thread is returned to constructor of class B but it goes first to the non-static initialization block before printing "Constructor". For better understanding debug it with some IDE, I prefer Eclipse.
Initializer block contains the code that is always executed whenever
an instance is created. It is used to declare/initialise the common
part of various constructors of a class.
The order of initialization constructors and initializer block doesn’t matter, initializer block is always executed before constructor.
What if we want to execute some code once for all objects of a class?
We use Static Block in Java.
In addition to what was said in previous answers, blocks can be synchronized .. never felt I need to use it, however,it's there
Initialization blocks are executed whenever the class is initialized and before constructors are invoked. They are typically placed above the constructors within braces. It is not at all necessary to include them in your classes.
They are typically used to initialize reference variables. This page gives a good explanation
The question is not entirely clear, but here's a brief description of ways you can initialise data in an object. Let's suppose you have a class A that holds a list of objects.
1) Put initial values in the field declaration:
class A {
private List<Object> data = new ArrayList<Object>();
}
2) Assign initial values in the constructor:
class A {
private List<Object> data;
public A() {
data = new ArrayList<Object>();
}
}
These both assume that you do not want to pass "data" as a constructor argument.
Things get a little tricky if you mix overloaded constructors with internal data like above. Consider:
class B {
private List<Object> data;
private String name;
private String userFriendlyName;
public B() {
data = new ArrayList<Object>();
name = "Default name";
userFriendlyName = "Default user friendly name";
}
public B(String name) {
data = new ArrayList<Object>();
this.name = name;
userFriendlyName = name;
}
public B(String name, String userFriendlyName) {
data = new ArrayList<Object>();
this.name = name;
this.userFriendlyName = userFriendlyName;
}
}
Notice that there is a lot of repeated code. You can fix this by making constructors call each other, or you can have a private initialisation method that each constructor calls:
class B {
private List<Object> data;
private String name;
private String userFriendlyName;
public B() {
this("Default name", "Default user friendly name");
}
public B(String name) {
this(name, name);
}
public B(String name, String userFriendlyName) {
data = new ArrayList<Object>();
this.name = name;
this.userFriendlyName = userFriendlyName;
}
}
or
class B {
private List<Object> data;
private String name;
private String userFriendlyName;
public B() {
init("Default name", "Default user friendly name");
}
public B(String name) {
init(name, name);
}
public B(String name, String userFriendlyName) {
init(name, userFriendlyName);
}
private void init(String _name, String _userFriendlyName) {
data = new ArrayList<Object>();
this.name = name;
this.userFriendlyName = userFriendlyName;
}
}
The two are (more or less) equivalent.
I hope that gives you some hints on how to initialise data in your objects. I won't talk about static initialisation blocks as that's probably a bit advanced at the moment.
EDIT: I've interpreted your question as "how do I initialise my instance variables", not "how do initialiser blocks work" as initialiser blocks are a relatively advanced concept, and from the tone of the question it seems you're asking about the simpler concept. I could be wrong.
public class StaticInitializationBlock {
static int staticVariable;
int instanceVariable;
// Static Initialization Block
static {
System.out.println("Static block");
staticVariable = 5;
}
// Instance Initialization Block
{
instanceVariable = 7;
System.out.println("Instance Block");
System.out.println(staticVariable);
System.out.println(instanceVariable);
staticVariable = 10;
}
public StaticInitializationBlock() {
System.out.println("Constructor");
}
public static void main(String[] args) {
new StaticInitializationBlock();
new StaticInitializationBlock();
}
}
Output:
Static block
Instance Block
5
7
Constructor
Instance Block
10
7
Constructor
Just to add to the excellent answers from #aioobe and #Biman Tripathy.
A static initializer is the equivalent of a constructor in the static context. which is needed to setup the static environment.
A instance initializer is best for anonymous inner classes.
It is also possible to have multiple initializer blocks in class
When we have multiple initializer blocks they are executed (actually copied to constructors by JVM) in the order they appear
Order of initializer blocks matters, but order of initializer blocks mixed with Constructors doesn't
Abstract classes can also have both static and instance initializer blocks.
Code Demo -
abstract class Aircraft {
protected Integer seatCapacity;
{ // Initial block 1, Before Constructor
System.out.println("Executing: Initial Block 1");
}
Aircraft() {
System.out.println("Executing: Aircraft constructor");
}
{ // Initial block 2, After Constructor
System.out.println("Executing: Initial Block 2");
}
}
class SupersonicAircraft extends Aircraft {
{ // Initial block 3, Internalizing a instance variable
seatCapacity = 300;
System.out.println("Executing: Initial Block 3");
}
{ // Initial block 4
System.out.println("Executing: Initial Block 4");
}
SupersonicAircraft() {
System.out.println("Executing: SupersonicAircraft constructor");
}
}
An instance creation of SupersonicAircraft will produce logs in below order
Executing: Initial Block 1
Executing: Initial Block 2
Executing: Aircraft constructor
Executing: Initial Block 3
Executing: Initial Block 4
Executing: SupersonicAircraft constructor
Seat Capacity - 300
This is the code I'm running , the output of this code is 4 2 1 3 , could someone please explain why the result was printed in this order.
public class goFuncTest {
goFuncTest()
{
System.out.print("1 ");
}
{
System.out.print("2 ");
}
public static void main(String[] args)
{
new goFuncTest().go();
}
void go()
{
System.out.print("3 ");
}
static
{
System.out.print("4 ");
}
}
Based on your recent question edit, your output will be 4 2 1 3. The static initializers are run first, then the instance initializers. If you had multiple initializers of the same type, they would execute in the order they appear in the class.
// static initializer first
static {
System.out.print("4 ");
}
// then instance initializer
{
System.out.print("2 ");
}
Next the constructor fires up, which gives you:
goFuncTest()
{
System.out.print("1 ");
}
finally the method is invoked:
void go()
{
System.out.print("3 ");
}
As JB Nizet pointed out in first comment, result should be 2,4,3,1.
And coming to the order, static blocks executes first and then initialization blocks. In your code there are no static blocks and only inti blocks.
The order of initialization block execution is the order they placed in source code -2,4.
And remaining two results as per constructor and method call. 1,3
Now you can see the answer right ?
Reason:
You have instance block which gets executed in sequence in which appear in your class definition. So 2 comes first and then 4 and hence output 2 4
Next you are calling new goFuncTest(), which is going to call your constructor and hence you will see 1 in the output.
Now on your instance you are calling go method which prints 3.
It seems the main confusion is just due to not understanding the various blocks that a class can have;
this answer gives a nice example and explanation;
Here's the code they give:
public class Test {
static int staticVariable;
int nonStaticVariable;
// Static initialization block:
// Runs once (when the class is initialized).
static {
System.out.println("Static initalization.");
staticVariable = 5;
}
// Instance initialization block:
// Runs before the constructor each time you instantiate an object
{
System.out.println("Instance initialization.");
nonStaticVariable = 7;
}
public Test() {
System.out.println("Constructor.");
}
public static void main(String[] args) {
new Test();
new Test();
}
}
This class has a static initialiser, an instance initialisation block, a constructor, and a class method.
static initialiser: static {...}
instance initialiser: {...}
constructor: Public ClassName(){...}
class method: Public Static Whatever classMethod(String[] args){...}
Each of these is called under different circumstances; the static initialiser is called when the class is loaded, there's no other way to call it, you can't even do it via reflection, as it's never represented by a method instance, it is called by the JVM.
the instance initialiser is called whenever you create an instance of the class - before the constructor.
You can have multiple static initialisers, and multiple instance initialisers, and they are executed in the order they appear in the code.
constructor and class method you presumably already know about.
In your example, it would probably be a little more helpful to rearrange the code slightly, to better reflect that hierarchy;
public class goFuncTest {
//static instance initialiser
static {
System.out.print("4 ");
}
//instance initialiser
{
System.out.print("2 ");
}
//Constructor
goFuncTest(){
System.out.print("1 ");
}
//Class method
void go(){
System.out.print("3 ");
}
public static void main(String[] args){
new goFuncTest().go();
}
}
(editted to add in the static keyword)