danidiaz danidiaz - 3 years ago 134
Java Question

How to allow a more precise return type in this use of generics?

I'm trying to model something like a "dynamic Enum" in Java. There is a generic inteface

Domain
which represents a set of allowable values, and an interface
Point
that represents a particular value. Like this:

public interface Domain<D extends Domain<D>> {

Set<Point<D>> points();

}

public interface Point<D> { // D works a bit like a phantom type

public D type();

}


My intention is to statically forbid accidental mixing of
Point
s from different
Domain
types.

I have the following
Domain
implementation:

public final class Symbols implements Domain<Symbols> {

final Set<Point<Symbols>> symbols = new HashSet<>();

public Symbols(final Set<String> values) {
super();
for (String value : values) {
this.symbols.add(new SymbolPoint(value));
}
}

@Override
public Set<Point<Symbols>> points() {
return symbols;
}

public class SymbolPoint implements Point<Symbols> {

private final String symbol;

...
}
}


It seems to work OK, but now I've hit a roadblock. I want the
points()
method of
Symbols
to return the type
Set<SymbolPoint>
. Which of course doesn't work because
Set<SymbolPoint>
is not a subtype of
Set<Point<Symbols>>
. How to make it work?

Answer Source

Your interface Domain should accept a wildcard for its points method.

interface Domain<D extends Domain<D>> {

    Set<? extends Point<D>> points();

}

You can now change Set<Point<Symbols>> to Set<SymbolPoint> in Symbols#points.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download