[英]Why doesn't this generic method accept any type?
In the code below, when I call getList()
I am not able to specify <T>
. 在下面的代码中,当我调用
getList()
我无法指定<T>
。 getList<T>()
does not compile. getList<T>()
不编译。
Instead, I may only call getList()
- but then <T>
is always simply <Event>
. 相反,我可能只调用
getList()
- 但<T>
总是只是<Event>
。
Why is this? 为什么是这样?
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 { }
It appears that Java won't accept a <T>
as the type argument to a simple name such as getList()
. Java似乎不接受
<T>
作为简单名称(如getList()
的类型参数。 But it will accept it if you explicitly state this.
但如果你明确说明
this.
它会接受它this.
when calling the method: 在调用方法时:
this.<T>getList().add(subscriber);
I believe the right answer is to make Foo
into Foo<T extends Event>
so that when in Foo
T
is defined. 我相信正确的答案是让
Foo
成为Foo<T extends Event>
以便在定义Foo
T
时。
Otherwise, try this.<T>getList()
. 否则,试试
this.<T>getList()
。 This is how this is done for statics MyClass.<String>someMethod()
. 这是静态
MyClass.<String>someMethod()
。 Not sure if it will also work for an instance method. 不确定它是否也适用于实例方法。 Again, the best answer is to make
Foo
generic. 同样,最好的答案是让
Foo
变得通用。
The T
from you example is extending Event
in both methods of Foo
class. 你的例子中的
T
是在Foo
类的两个方法中扩展Event
。 Well that implicitly means you Foo
class is working only with <T extends Event>
type inference. 好吧, 隐含意味着你
Foo
类只与<T extends Event>
类型推断一起工作。 Unfortunately, your T
is defined only at method scope. 不幸的是,您的
T
仅在方法范围内定义。 For humans all looks alright. 对于人类来说,所有人看起 But compiler is a bit different.
但编译器有点不同。 Compiler doesn't believe you and it's not able to figure out implicit informations, however they are just fine, logically.
编译器不相信你,也无法找出隐含的信息,但它们在逻辑上也很好。 You did not define your
T
at Class scope and the compiler did not figure out you are using the same type inference in both methods. 您没有在Class范围内定义
T
,并且编译器没有发现您在两种方法中都使用相同的类型推断。 So, compiler wont let you mix these method together. 所以,编译器不会让你把这些方法混合在一起。
So, the solution should explicitly define type inference is for Class scope use not only for method scope. 因此,解决方案应该明确定义类型推断是针对类范围使用的,不仅仅是方法范围。
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 {
}
Perhaps you need to be a little more gentle with Java. 也许你需要对Java更温和一点。 This seems to work without warnings:
这似乎没有警告:
HashSet<Subscriber<T>> list = getList();
list.add(subscriber);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.