3

在下面的代码中,当我打电话时,我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 { }
4

4 回答 4

1

我相信正确的答案是 make FoointoFoo<T extends Event>以便Foo T定义 when in 。

否则,请尝试this.<T>getList(). 这就是对 statics 的处理方式MyClass.<String>someMethod()。不确定它是否也适用于实例方法。同样,最好的答案是Foo通用的。

于 2013-10-30T21:58:58.230 回答
1

似乎 Java 不接受 a<T>作为简单名称的类型参数,例如getList(). 但是如果你this.在调用方法时明确声明它会接受它:

this.<T>getList().add(subscriber);
于 2013-10-30T21:57:45.130 回答
0

from you 示例在类的两种方法中都进行了T扩展。嗯,这隐含地意味着你的类只使用类型推断。不幸的是,您仅在方法范围内定义。对于人类来说,一切看起来都很好。但是编译器有点不同。编译器不相信你,它无法找出隐含的信息,但是它们在逻辑上很好。您没有定义at Class 范围,编译器没有发现您在两种方法中使用相同的类型推断。因此,编译器不会让您将这些方法混合在一起。EventFooFoo<T extends Event>TT

因此,解决方案应该明确定义类型推断是为了类范围使用,而不仅仅是方法范围。

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 {

}
于 2013-10-30T22:31:22.587 回答
0

也许您需要对 Java 更温和一点。这似乎在没有警告的情况下工作:

HashSet<Subscriber<T>> list = getList();
list.add(subscriber);
于 2013-10-30T23:02:05.973 回答