I'm toying around with instance control flow and static control flow, notice the code below
class A {
{
m1();
}
A(){
System.out.println("A constructor");
}
void m1(){
System.out.println("A m1");
}
}
public class Main extends A {
public static void main(String[] args) throws Exception {
Main m = new Main();
}
void m1(){
System.out.println("Main m1");
}
}
The output for the code is:
Main m1
A constructor
I know this is because:
First, static blocks and variables were identified top-to-bottom parent-to-child, in this case there was just a main()
that was static.
Second, the static blocks and variable assignments are executed, so main()
's execution starts, and there is an attempt to create a new Main
object.
So third, the instance blocks and variables of parent class will be identified. Then they will be executed top-bottom. (After that the constructor of the parent class will run, then the instance blocks and variables of child class will be identified, following which they will be executed top-bottom and finally the child class' constructor will execute).
I have two questions(Why? Purely for academic reasons, I'm still learning Java):
m1()
methods are non-static, is it possible to invoke A's m1() from the instance block of A? I tried doing a this.m1()
but that still invoked Main's m1().(Why?)
m1()
methods are static, is it possible to invoke Main's m1() from the instance block of A? (I'm guessing no but I'm not certain).
After compilation is done java 8 compiler your code looks like this:
class A {
A() {
this.m1(); // at runtime this refers to Main class instance
System.out.println("A constructor");
}
void m1() {
System.out.println("A m1");
}
}
public class Main extends A {
public Main() { }
public static void main(String[] args) throws Exception {
Main m = new Main();
m.m1();
}
void m1() {
System.out.println("Main m1");
}
}
Now to answer your first question: No. You cannot unless you are creating an instance of A(actual object of A).
To your second question: after making both m1's static compilation looks like this:
class A {
A() {
m1(); // resolves to A's m1
System.out.println("A constructor");
}
static void m1() {
System.out.println("A m1");
}
}
public class Main extends A {
public Main() {
}
public static void main(String[] args) throws Exception {
new Main();
}
static void m1() {
System.out.println("Main m1");
}
}
Now no matter which instance(A or Main) you create you will see A's m1 excuted.