left and right objects are evaluated / resolved during runtime or compile-time?

Tim Daiu :

Referring to a book exercise...

Having the following code..

Left left = createLeftInstance ();
Right right = createRightInstance ();

...and keeping in consideration that both the above mentioned methods can return instance of all the sub-classes of Left and Right, in Java the call of the following method...

left.invoke (right);

how is resolved:

  • A) basing on runtime type of left and compile-time of right
  • B) basing on compile-time type of left and runtime of right
  • C) basing on compile-time type of left and compile-time of right
  • D) basing on runtime type of left and runtime of right
peter.petrov :

A) is the correct answer here.

The following code demonstrates that.

    public class Main001 {

        public static void main(String[] args) {
            A right = createRightInstance();
            B left = createLeftInstance();

            left.invoke(right);
            System.out.println("Done!!!");
        }

        public static B createLeftInstance() {
            return new B2();
        }

        public static A createRightInstance() {
            return new A2();
        }

    }

    class A{

    }

    class A1 extends A{

    }

    class A2 extends A1{

    }

    class B{
        public void invoke(A x) {
            System.out.println("Invoking method A on B with argument " + x.getClass().getName());
        }
        public void invoke(A1 x) {
            System.out.println("Invoking method A1 on B with argument " + x.getClass().getName());
        }
        public void invoke(A2 x) {
            System.out.println("Invoking method A2 on B with argument " + x.getClass().getName());
        }
    }

    class B1 extends B{
        public void invoke(A x) {
            System.out.println("Invoking method A on B1 with argument " + x.getClass().getName());
        }
        public void invoke(A1 x) {
            System.out.println("Invoking method A1 on B1 with argument " + x.getClass().getName());
        }
        public void invoke(A2 x) {
            System.out.println("Invoking method A2 on B1 with argument " + x.getClass().getName());
        }

    }

    class B2 extends B1{
        public void invoke(A x) {
            System.out.println("Invoking method A on B2 with argument " + x.getClass().getName());
        }
        public void invoke(A1 x) {
            System.out.println("Invoking method A1 on B2 with argument " + x.getClass().getName());
        }
        public void invoke(A2 x) {
            System.out.println("Invoking method A2 on B2 with argument " + x.getClass().getName());
        }
    }

This example prints

Invoking method A on B2 with argument A2
Done!!!

which means A) is the correct answer.

Why does it mean that?

Well... because:
1) a method from the B2 class is invoked (as the output says) and B2 is the runtime type of left (the compile time type of left is B).
2) a method with parameter A is invoked (note that A is the compile-time type of right), even though the runtime type of right is A2. Compile time type of right is just the type with which right is declared i.e. A. Runtime type of right is the actual type of the argument i.e. A2 (see the output, it says with argument A2 there).

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=78633&siteId=1