Reputation: 91
I have a class
public abstract class AbstractE<T, E extends Enum<E> & Flags>
{
public interface Flags{} /*marker interface*/
//...
//other code
}
and an interface
public interface IXYZAdapter
{
public <E extends Enum<E> & Flags> Set<E> getFlags();
}
Where Flags is an interface defined in AbstractE itself.
M extends AbstractE thus:
public class M extends AbstractE<Long, M.EF> implements IXYZAdapter
{
public enum EF implements AbstractE.Flags{flag1, flag2}
@Override /*from IXYZAdapter*/
public Set<M.EF> getFlags()
{return EnumSet.allOf(EF.class);}
}
Now, from the main code, I try to get a handle on the interface IXYZAdapter and invoke the getFlags method
IXYZAdapter adapter = (IXYZAdapter)m; //where m is an instance of AbstractE
Set s = adapter.getFlags();
I get the following compile time error in the main program last line (Set s = adapter.getFlags();)
invalid inferred types for E; inferred type does not conform to declared bound(s)
inferred: AbstractE.Flags bound(s): java.lang.Enum<AbstractE.Flags>,AbstractE.Flags
What am I doing wrong? I am using Java 6
Edited to specify the error location
Upvotes: 3
Views: 3712
Reputation: 88707
Try this:
public interface IXYZAdapter <E extends Enum<E> & AbstractE.Flags>
{
public Set<E> getFlags();
}
And
public class M extends AbstractE<Long, M.EF> implements IXYZAdapter<M.EF>
{
}
Or
Set<M.EF> s = adapter.getFlags();
The problem is that with Set s = adapter.getFlags();
The system doesn't know which type to infer for E in IXYZAdapter and thus the E in AbstractE doesn't match.
Edit:
Another option might be:
interface IXYZAdapter <E extends Enum<E> & AbstractE.Flags>
{
public Set<? extends E> getFlags();
}
class M extends AbstractE<Long, M.EF> implements IXYZAdapter<M.EF>
{
public enum EF implements AbstractE.Flags{flag1, flag2}
public Set<? extends M.EF> getFlags()
{return EnumSet.allOf(EF.class);}
}
And the call: Set<? extends AbstractE.Flags> s = adapter.getFlags();
This would allow you to get a set of flags without casting and force the flags to be declared as enum.
Upvotes: 2
Reputation: 2777
using the first solution thomas provided, the main method can be written like this to become warning free without actually having to know about the enum type:
public static void main(String[] args) {
M m = new M();
IXYZAdapter<?> adapter = (IXYZAdapter<?>)m;
Set<?> flags = adapter.getFlags();
Iterator<?> it = flags.iterator();
while(it.hasNext()) {
System.out.println(it.next());
}
}
Upvotes: 0