2011-04-17 84 views
0

有三个Java 1.6接口继承一个从另一个:如何在界面中使返回类型泛型?

interface First<T extends First<T>> { 
    T me(); 
} 
interface Second<T extends Second<T>> extends First<T> { 
} 
interface Third<T extends Third<T>> extends Second<T> { 
    void foo(); 
} 

现在我很期待这一个工作,但没有:

// somewhere later 
public void bar(Third t) { 
    t.me().foo(); 
} 

编译器说,t.me()Second类型。我究竟做错了什么?

+1

当我尝试它时,编译器似乎认为t.me()是第一种类型! – 2011-04-17 12:32:47

+0

@Tom更糟。你知道如何让编译器认为't.me()'是'Third'类型吗? – yegor256 2011-04-17 12:36:48

+1

正如BeyoncéKnowles所说(稍微解释一下),如果你想使用它,你应该在其上放置一个类型参数。 – 2011-04-17 12:40:59

回答

1

试试这个:

public <T extends Third<T>> void bar(Third<T> t) { 
    t.me().foo(); 
} 
+0

可否请您再次查看我的问题,最后我进行了更正。我无法控制't'的实例化。这对我来说是'Third'的类型。 – yegor256 2011-04-17 12:35:46

+0

@yegor:看到我更新的答案。 – 2011-04-17 12:40:16

1

的问题是,你有没有在T的声明,这使得原始类型提供的类型参数。所有关于泛型的推理都因此失去作用。因为me()被声明为返回T中的类型T,所以用T extends First进行参数化,其原始类型为First,这就是编译器将它视为即使它来自Third的情况。

如果你要提供一个参数给任何值的t - ! - 编译器将能够使用关于泛型的规则,并且可以计算出me()返回第三个。例如,像Oli建议的那样写一些Foo类的话会做到这一点,就像将它绑定到?一样。

如果将第三个实例作为原始类型的变量,则将其分配给类型为Third的变量。这是合法的,从来没有检查过,并会让你觉得你应该在哪里。