在下面的代码中,当我致电getList()
时,我无法指定<T>
。 getList<T>()
无法编译。
相反,我只能致电getList()
- 但<T>
始终只是<Event>
。
为什么会这样?
class Foo
{
public static void main (String[] args) throws java.lang.Exception
{
// For the sake of a complete example - the next method has
// my question.
Foo f = new Foo();
f.register(new Subscriber<MyEvent>() {
public void handle(MyEvent event){};
});
}
public <T extends Event> void register(Subscriber<T> subscriber) {
// Below won't work. I can't specify <T>, so getList()
// will return a HashSet<Subscriber<Event>>, to which I cannot
// add the Subscriber<T>!
getList().add(subscriber);
// Why can't I call getList<T>().add(subscriber) ?
}
private <T extends Event> HashSet<Subscriber<T>> getList() {
// For the sake of example, simply return a new HashSet.
return new HashSet<Subscriber<T>>();
}
}
interface Subscriber<T extends Event> {
public void handle(T event);
}
interface Event { }
class MyEvent implements Event { }
答案 0 :(得分:1)
似乎Java不会接受<T>
作为简单名称(如getList()
)的类型参数。但是如果你在调用方法时明确说明this.
,它会接受它:
this.<T>getList().add(subscriber);
答案 1 :(得分:1)
我认为正确的答案是将Foo
变为Foo<T extends Event>
,以便在定义Foo
T
时。
否则,请尝试this.<T>getList()
。这是静态MyClass.<String>someMethod()
的完成方式。不确定它是否也适用于实例方法。同样,最好的答案是使Foo
通用。
答案 2 :(得分:0)
示例中的T
正在Event
类的两种方法中扩展Foo
。那么含蓄地意味着你Foo
类仅适用于<T extends Event>
类型推断。不幸的是,您的T
仅在方法范围内定义。对于人类来说,所有人看起但编译器有点不同。编译器不相信你,也无法找出隐含的信息,但它们在逻辑上也很好。您没有在Class范围中定义T
,并且编译器没有发现您在两种方法中都使用相同的类型推断。所以,编译器不会让你把这些方法混合在一起。
因此,解决方案应该明确定义类型推断是针对类范围使用的,不仅仅是方法范围。
class Foo<T extends Event>
{
public static void main (String[] args) throws java.lang.Exception
{
// For the sake of a complete example - the next method has
// my question.
Foo<MyEvent> f = new Foo<MyEvent>();
f.register(new Subscriber<MyEvent>() {
public void handle(MyEvent event){};
});
}
public void register(Subscriber<T> subscriber) {
// Below won't work. I can't specify <T>, so getList()
// will return a HashSet<Subscriber<Event>>, to which I cannot
// add the Subscriber<T>!
getList().add(subscriber);
// Why can't I call getList<T>().add(subscriber) ?
}
private HashSet<Subscriber<T>> getList() {
// For the sake of example, simply return a new HashSet.
return new HashSet<Subscriber<T>>();
}
}
interface Subscriber<T extends Event> {
public void handle(T event);
}
class MyEvent extends Event {
}
class Event {
}
答案 3 :(得分:0)
也许你需要对Java更温和一点。这似乎没有任何警告:
HashSet<Subscriber<T>> list = getList();
list.add(subscriber);