Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
187 views
in Technique[技术] by (71.8m points)

java - Self bound generic type with fluent interface and inheritance

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>
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...