Home > OS >  Does super() run in compiletime and this() run in runtime? and why?
Does super() run in compiletime and this() run in runtime? and why?

Time:12-18

in this program it will print "Student 1 Person 1 Undergrad 2 "

that means super.method1() > super() of student this.method2() this of Undergrad()

Does super() run in compiletime and this() run in runtime? and why ?

public class Person {
    public void method1() {
        System.out.print("Person 1 ");
    }
    public void method2()  {
        System.out.print("Person 2 ");
    }
}
public class Student extends Person {
    public void method1() {
        System.out.print("Student 1 ");
        super.method1();
        this.method2();
    }
    public void method2() {
        System.out.print("Student 2 ");
    }
}
public class Undergrad extends Student {
     /*public void method1() {
         System.out.print("ahmed");
     }*/
     public void method2() {
         System.out.print("Undergrad 2 ");
     }
}
public class main {
    
    static void main(){
        Person u = new Undergrad();
        u.method1();    
        
    }

}

I expect output: It will cause an infinite execution, printing "Student 1" over and over.

output was:"Student 1 Person 1 Undergrad 2 ".

CodePudding user response:

You are correct in that super.xxx() vs this.xxx() has some sort of a "compile time vs runtime" distinction, but it is certainly not that super.xxx() is "run" at compile time.

A more accurate wording would be, the method that will be called by a super.xxx call is decided at compile time (statically dispatched). And the method that will be called by a this.xxx call is decided at runtime (dynamically dispatched).

You can see this by comparing the clauses in the Java Language Specification, in the sections about processing method invocations. The important steps that differs between super.xxx and this.xxx are (emphasis mine):

Compile-Time Step 1: Determine Type to Search

If the form is Primary . [TypeArguments] Identifier, then let T be the type of the Primary expression. The type to search is T if T is a class or interface type, or the upper bound of T if T is a type variable.

If the form is super . [TypeArguments] Identifier, then the type to search is the direct superclass type of the class whose declaration contains the method invocation.

Notice that this is done at compile time. The call super.method1(); in Student will cause a search in Person because Person is "the class whose declaration contains the method invocation". Eventually, we'll find Person.method1 in a later step.

On the other hand, the call this.method2(); in Student will search in Student.

Locate Method to Invoke

  • Let Q be the qualifying class or interface of the method invocation (§13.1).

  • Let m be the method found in Q or a superclass or superinterface of Q. (Note that m was merely the name of the method in the previous section; here it is the actual declaration.)

  • Let C be the class or interface that declares m.

[...]

  • If the invocation mode is super, overriding is not allowed. Method m of class or interface C is the one to be invoked. If m is abstract, an AbstractMethodError is thrown.

[...]

  • Otherwise, the invocation mode is interface or virtual.

    If the method m of class or interface C is private, then it is the method to be invoked.

    Otherwise, overriding may occur. A dynamic method lookup, specified below, is used to locate the method to invoke. The lookup procedure starts from class R, the actual run-time class of the target object.

This is a runtime step. For super.method1();, C is Person (since we found Person.method1()), and the invocation mode is super, so that is what is invoked.

For this.method2();, a dynamic method lookup occurs, which in this case involves finding the appropriate overridden method depending on the runtime type of this.

  • Related