运行时签名是什么?

2024-05-01

当涉及到有界类型时,我对 Java 的类型擦除有一些理解上的问题。考虑一下:

class Event {} // From the API
class FooEvent extends Event {}

abstract class Foo<EventType extends Event> {
    public abstract <E extends EventType> void onEventCaught(E event);
}

class Bar extends Foo<FooEvent> {
    @Override
    public void onEventCaught(FooEvent event) {

    }
}

显然这编译没有问题。我问自己的问题是,参数类型是Bar#onEventCaught()在这里声明(例如,反射认为什么)?

Is it onEventCaught(FooEvent event)或者可能onEventCaught(Event event)?


来自Java语言规范 http://docs.oracle.com/javase/specs/jls/se8/html/jls-4.html#jls-4.6

类型变量(第 4.4 节)的擦除是其最左边界的擦除。

You have

<EventType extends Event> 

and

<E extends EventType>

最左边界为E is EventType,这是另一个类型变量,其最左边界是Event。所以擦除E in

public abstract <E extends EventType> void onEventCaught(E event);

is Event.

类型变量确实出现在.class文件,您可以在反射中使用它们。

Class<?> clazz = Foo.class;
TypeVariable typeVariable = clazz.getTypeParameters()[0];
Type type = typeVariable.getBounds()[0];

System.out.println(typeVariable);
System.out.println(type);

prints

EventType
class com.example.Event
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

运行时签名是什么? 的相关文章

随机推荐