有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

Java通用多类型边界擦除,我们应该在边界列表的开头放置哪些类/接口

在泛型类实现中,我们可以使用类型边界。但在编译类时,编译器会删除类型边界,并用第一个边界替换类型变量

那么,如果我们调用的方法属于第一种类型以外的类型,会发生什么呢?编译器如何解决这个问题

为了提高类的效率,我们应该为第一种类型使用哪些类/接口


共 (2) 个答案

  1. # 1 楼答案

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

    这就是多态性实现相关的问题。Java编译器使用虚拟表来解析要调用的方法

    一些相关问题:Java method table

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

    同样,JVM使用虚拟表,并且已经关心我们的效率,在大多数情况下,您不应该关心这些事情。它允许您更多地考虑程序的总体效率

  2. # 2 楼答案

    以下代码:

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

    编译成以下字节码

      <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
    

    因此,在字节码中,第一个参数具有Test1类型,并且无论何时将其用作Test2,编译器都会插入一个选中的强制转换。这段代码将使用Java1.4编写

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

    您不太可能观察到由该转换引起的任何性能差异,但了解该代码是如何编译成字节码的可能会很有用