Static and Dynamic Assignments

The three main features of JAVA are inheritance, encapsulation, and polymorphism. The dispatch call process will reveal some of the most basic manifestations of polymorphism, such as override and overload.

1. Static Assignment

Before introducing static assignment, let's look at a piece of code

public class StaticDispatch {
    static abstract class Human{

    }
    static class Man extends Human{

    }
    static class Woman extends Human{

    }
    public void sayHello(Human human){
        System.out.println("hello,guy");
    }
    public void sayHello(Man man){
        System.out.println("hello,man");
    }
    public void sayHello(Woman woman){
        System.out.println("hello,woman");
    }

    public static void main(String[] args) {
        Human man = new Man();
        Human woman = new Woman();
        StaticDispatch dispatch = new StaticDispatch();
        dispatch.sayHello(man);
        dispatch.sayHello(woman);
    }
}

Output results:

hello,guy
hello,guy

Why does a virtual machine execute an overloaded version with the parameter Human? Why not analyze this line of code first?

Human man = new Man();

Here Human is called the static type (or appearance type) of the man object, and Man is called the actual type (or runtime type) of the variable.Static types and actual types may change at runtime, but changes to static types occur only when they are in use, static types of variables themselves are not changed, and the final static type is known at compile time, while changes to actual types can only be determined at runtime.

For overloaded methods, the virtual machine relies on the static type of the parameter as the static type is known to the compiler and the JVM needs to determine which overloaded method to call at compile time, obviously not the actual type that will only be determined at run time.

Therefore, all assignment actions that rely on static types to determine the version of a method's execution are referred to as static assignments.

2. Dynamic Assignment

Let's start with the next piece of code

public class DynamicDispatch {
    static abstract class Human{
        protected abstract void sayHello();
    }
    static class Man extends Human{

        @Override
        protected void sayHello() {
            System.out.println("man say hello");
        }
    }
    static class Woman extends Human{

        @Override
        protected void sayHello() {
            System.out.println("woman say hello");
        }
    }

    public static void main(String[] args) {
        Human man = new Man();
        Human woman = new Woman();
        man.sayHello();
        woman.sayHello();
        man = new Woman();
        man.sayHello();
    }
}

Output results:

man say hello
woman say hello
woman say hello

As a result, the call to sayHello() is determined by the actual type of the variable, because at this point sayHello()The method parameter list of the method is the same and does not constitute an overloaded method. From the decompiled byte code instruction, the method should be invoked after the corresponding object is obtained, that is, Figures 1617 and 2021 below, the man and woman objects are loaded, and then the method is invoked.

public static void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=2, locals=3, args_size=1
         0: new           #2                  // class com/cry/spring/Extend/DynamicDispatch$Man
         3: dup
         4: invokespecial #3                  // Method com/cry/spring/Extend/DynamicDispatch$Man."<init>":()V
         7: astore_1
         8: new           #4                  // class com/cry/spring/Extend/DynamicDispatch$Woman
        11: dup
        12: invokespecial #5                  // Method com/cry/spring/Extend/DynamicDispatch$Woman."<init>":()V
        15: astore_2
        16: aload_1
        17: invokevirtual #6                  // Method com/cry/spring/Extend/DynamicDispatch$Human.sayHello:()V
        20: aload_2
        21: invokevirtual #6                  // Method com/cry/spring/Extend/DynamicDispatch$Human.sayHello:()V
        24: new           #4                  // class com/cry/spring/Extend/DynamicDispatch$Woman
        27: dup
        28: invokespecial #5                  // Method com/cry/spring/Extend/DynamicDispatch$Woman."<init>":()V
        31: astore_1
        32: aload_1
        33: invokevirtual #6                  // Method com/cry/spring/Extend/DynamicDispatch$Human.sayHello:()V
        36: return

Unlike previous StaticDispatches, in StaticDispatch, the objects calling sayHello were dispatch es, and the objects calling methods in DynamicDispatch were two different objects, so different results would occur.

More recently, the invokevirtual directive, which resolves at run time, plays a major role in dynamic assignment:

1) Find the actual type of object that the first element on the top of the operand stack points to, and mark it as C.

2) If a method matching both the descriptor and the simple name is found in Class C, then the method privilege check is performed. If there is access privilege, the direct reference to the method is returned, and the lookup process ends; otherwise, an IllegalAccessError exception is thrown.

3) Otherwise, search and validate each parent of C in turn from bottom to top according to the inheritance relationship.

4) Throw an AbstractMethodError exception if no suitable method is found.

However, dynamic assignment is only valid for methods and not for fields.

public class FieldHasNoPolymorphic {
    static class Father{
        int money =1;
    }
    static class Son extends Father{
        int money =2;
    }

    public static void main(String[] args) {
        Father guy = new Son();
        System.out.println(guy.money);
    }
}

Output result is 1

That is, even if the subclass defines money, it will not be affected by dynamic assignment, because the field will not use the invokeDynamic directive, nor will it make virtual, in other words, the field will never participate in polymorphism.

Keywords: Java jvm

Added by Skittlewidth on Mon, 27 Sep 2021 20:25:19 +0300