问题
I am using a fluent interface with inheritance. I declared the base class Constructor protected so you cant create a Foo<Bar> which would result in a ClassCastException on calling add(). But i am having trouble with the static method that returns a new Foo instance.
public class Foo<T extends Foo<T>> // if i change to extends Foo i only get warnings
{
public static Foo<Foo> createFoo() // <-- error
{
return new Foo<Foo>(); // <-- error
}
protected Foo() {}
public T add()
{
//...
return (T)this;
}
}
public class Bar extends Foo<Bar>
{
public Bar sub()
{
//...
return this;
}
}
This is mostly an excercise(personal not homework) in Fluent Interfaces, Domain-specific language and Generics, so please dont ask what i need it for.
Edit: Eclipse error
Bound mismatch: The type Foo is not a valid substitute for the bounded parameter <T extends Foo<T>> of the type Foo<T>
回答1:
You essentially have a recursive type declaration.
Foo<T extends Foo<T>>
.
So let's say you have a Foo<Foo>
. That means T
is mapped to Foo
. But Foo
is not subtype of Foo<T>
, which in this case is Foo<Foo>
, so what you're really looking for is Foo<Foo<Foo>>
. But wait a minute, the innermost Foo
isn't typed, so I guess it's Foo<Foo<Foo<Foo>>>
...oh forget it!
To put a more understandable face on it, consider if you had Foo<T extends List<T>>
. What could you possibly use for T
in a declaration/instantiation of Foo
? List<String>
? List<List>
?
Edit
It looks like you found a way to "break" the recursion cycle. You eventually need to get to a reified type. In the same way that you found that ConcreteFoo
worked for you, you could similarly for the List
example above have some class ConreteListOfItself implements List<ConreteListOfItself>
that would break the recursion cycle.
来源:https://stackoverflow.com/questions/7959335/self-bound-generic-type-with-fluent-interface-and-inheritance