2011-04-17 113 views
2

这是Java 1.6接口:如何返回一个泛型类型而不明确指定其参数?

interface Foo<T extends Foo<T>> { 
} 

这是一个工厂,它应该返回"Foo<Foo>"

interface Factory { 
    <T extends Foo<T>> Foo<T> find(); 
} 

不能编译工厂类:

incompatible types; inferred type argument(s) java.lang.Object do not conform 
to bounds of type variable(s) T 
[ERROR] found : <T>Foo<T> 
[ERROR] required: java.lang.Object 

这里有什么问题?

回答

2

我可以编译工厂类:

class MyFoo implements Foo<MyFoo> { } 

    Foo<MyFoo> foo = new Factory() { 
     public <T extends Foo<T>> Foo<T> find() { 
      return null; 
     } 
    }.find(); 

然而,有用,因为该接口的实现可以得到的,因为里面find()代码有发现没有办法T在任何特定调用代表什么,因此不能实例化一个T

如果你的工厂应该只创建一个特定类型的实例,给工厂的类型参数:

interface Factory<T> { 
    T find(); 
} 

class MyFactory implements Factory<MyFoo> { 
    MyFoo find() { return new MyFoo(); } 
} 

如果它创建任意类型的实例,通过预期的类型find()

class Factory { 
    <T extends Foo<T>> find(Class<T> clazz) { 
     return clazz.newInstance(); 
    } 
} 

MyFoo myFoo = new Factory().find(MyFoo.class); 

最后,请注意工厂在存储库找到它们时创建对象。你是在声明一个存储库还是一个工厂?你的API的调用者可能会澄清一下。

+0

感谢您的解释,帮助很多。在我的用例中,我希望'Factory.find()'返回'Foo ',总是(在问题中提到)。在这种情况下,我应该如何声明'find()'? – yegor256 2011-04-17 15:00:05

+3

'Foo '不是一个完整的类型,因为'Foo'需要一个类型参数。也许'Foo '? – 2011-04-17 15:04:14

+0

@Paulo你是对的,'Foo '工作正常。如果您将它发布为答案,我很乐意将其选为最佳答案。 – yegor256 2011-04-17 15:10:58

相关问题