运行时签名是什么?

时间:2015-02-07 22:09:58

标签: java reflection type-erasure

当涉及到有界类型时,我在理解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()声明的,这里(如反思所思考的那样)?

onEventCaught(FooEvent event)还是onEventCaught(Event event)

1 个答案:

答案 0 :(得分:4)

来自Java Language Specification

  

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

你有

<EventType extends Event> 

<E extends EventType>

E的最左边界是EventType,这是另一个类型变量,其最左边界是Event。所以删除了E

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

Event

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

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

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

打印

EventType
class com.example.Event