Java 类型擦除和多重边界

问题描述 投票:0回答:5
我知道在 Java 泛型中,当使用具有多个边界的类型参数时,编译器会将类型信息删除到“最左边的边界”(即列表中的第一个类/枚举或接口)。 那么为什么下面的代码编译没有问题呢?

public class Generic<T extends Object & Appendable & AutoCloseable> { T t; T method() throws Exception { t.close(); char c='\u0000'; t.append(c); return t; } public <T> T method2(T t) { return t; } }

类型参数T不应该被视为Object吗? (因此不允许我调用 close() 或append())??

java generics type-parameter type-bounds
5个回答
0
投票
您应该阅读

桥接方法这里

当编译扩展参数化类或实现参数化接口的类或接口时,编译器可能需要创建一个称为桥接方法的合成方法,作为类型擦除过程的一部分。您通常不需要担心桥接方法,但如果桥接方法出现在堆栈跟踪中,您可能会感到困惑。


0
投票
您的案例包含

多重绑定

具有多个边界的类型变量是所有类型的子类型 列在绑定中。如果其中一个边界是类,则它必须是 首先指定。

因此调用AutoCloseable接口中包含的close()方法和Appendable接口中包含的append()方法在语法上是合法的。


0
投票
这是你的代码的反汇编。 变量

t

 是对象类型。
指令
checkcast
是在调用接口方法之前生成的。
如果 
t
 的值未实现该接口,则将抛出 ClassCastException。

Compiled from "Generic.java" public class Generic<T extends java.lang.Appendable & java.lang.AutoCloseable> { T t; public Generic(); Code: 0: aload_0 1: invokespecial #1 // Method java/lang/Object."<init>":()V 4: return T method() throws java.lang.Exception; Code: 0: aload_0 1: getfield #2 // Field t:Ljava/lang/Object; 4: checkcast #3 // class java/lang/AutoCloseable 7: invokeinterface #4, 1 // InterfaceMethod java/lang/AutoCloseable.close:()V 12: iconst_0 13: istore_1 14: aload_0 15: getfield #2 // Field t:Ljava/lang/Object; 18: checkcast #5 // class java/lang/Appendable 21: iload_1 22: invokeinterface #6, 2 // InterfaceMethod java/lang/Appendable.append:(C)Ljava/lang/Appendable; 27: pop 28: aload_0 29: getfield #2 // Field t:Ljava/lang/Object; 32: areturn public <T> T method2(T); Code: 0: aload_1 1: areturn }
    

0
投票
这本身并不是一个答案,只是这个

最左规则并不完全相关 - 我仍在尝试找出正确的JLS

部分(并不像我希望的那么容易),但是您可以从这里看到该类型
不是对象:

<T extends Object & Appendable & AutoCloseable> void whatType(T... args) { System.out.println(args.getClass().getComponentType().getSimpleName()); } new DeleteMe().whatType(); // prints AutoCloseable
    

0
投票
根据java文档,泛型类可以使用所有

bound中定义的所有方法。因此,允许使用 ObjectAppendableAutocloseable 的方法。类型擦除和允许的方法并不相互依赖。引入类型擦除只是为了防止运行时产生额外的开销。

© www.soinside.com 2019 - 2024. All rights reserved.