0

In generic class implementations we can use type bounds. But when the class is compiled the compiler erases the type bounds and replaces type variables with the first bound.

So what happens if we invoke a method belongs to a type other than first type? how does compiler resolve this?

What classes/ interfaces should we use for the first type for more efficiency of the class?

2 Answers2

1

The following code:

public class Test {
    <T extends Test1 & Test2> void f(T t) {
        t.foo1();
        t.foo2();
    }
}

interface Test1 {
    void foo1();
}

interface Test2 {
    void foo2();
}

Compiles into the following bytecode

  <T extends test.Test1 & test.Test2> void f(T);
    Code:
       0: aload_1
       1: invokeinterface #2,  1            // InterfaceMethod test/Test1.foo1:()V
       6: aload_1
       7: checkcast     #3                  // class test/Test2
      10: invokeinterface #4,  1            // InterfaceMethod test/Test2.foo2:()V
      15: return

So within bytecode the first argument have Test1 type and whenever you're using it as a Test2, compiler inserts a checked cast. This code would be written with Java 1.4 as

void f(Test1 t) {
    t.foo1();
    ((Test2) t).foo2();
}

It is extremely unlikely that you would be able to observe any performance difference caused by that cast, but it might be useful to understand how that code is compiled into bytecode.

vbezhenar
  • 11,148
  • 9
  • 49
  • 63
0

So what happens if we invoke a method belongs to a type other than first type? how does compiler resolve this?

That's polymorphism implementation related question. The Java compiler uses the virtual table for resolving which method to call.

Some related question: Java method table

What classes/interfaces should we use for the first type for more efficiency of the class?

Again, JVM uses the virtual table and already cared about efficiency for us and in most cases you shouldn't care about such things. It allows you to think more about program's efficiency in general.