Richard Sand
Richard Sand

Reputation: 674

Java factory uses generics and Supplier interface, but still needs typecasts, something is not right

I'm trying to use generics and a Supplier to avoid needing to typecast the result of my static factory method but failing. I think I'm close, can someone point out what I'm doing wrong here?

Here is the parameterized interface IManager:

public interface IManager<C extends IConfigObject> {

Here is an abstract base class AbstractManager, which includes the static factory method:

public abstract class AbstractManager<C extends IConfigObject> implements IManager<C> {
    ....
    public static  <C extends IConfigObject> AbstractManager<C> getInstance(Supplier<? extends AbstractManager<C>> supplier) {

Next, here is a concrete implementation called MyManager which is parameterized with MyConfigObject, which in turn implements IConfigObject:

public final class MyManager extends AbstractManager<MyConfigObject> {

And finally, the main() code:

Supplier<MyManager> supplier = MyManager::new;
MyManager manager = (MyManager) AbstractManager.getInstance(supplier);

If I don't have the cast in there, I get a compiler error:

Type mismatch: cannot convert from AbstractManager to MyManager

Any suggestions?

Upvotes: 1

Views: 1297

Answers (1)

Michael
Michael

Reputation: 44150

Your problem is here: Supplier<? extends AbstractManager<C>>. By using the wildcard, you're saying "I don't care about the actual type" but you do.

The key here is to first use two type parameters, the second of which relies on the first one (I used M for "manager"):

public static <C extends IConfigObject, M extends AbstractManager<C>>
    M getInstance(Supplier<M> supplier)
{
    // ...
}

If you're not using C in the method body, you could refactor it to:

public static <M extends AbstractManager<? extends IConfigObject>>
    M getInstance(Supplier<M> supplier)
{
    // ...
}

Upvotes: 3

Related Questions