So, I have this public interface NodeLevel<E extends NodeLevelEnum>
, which has methods public E getParent()
and public E getEnum()
. An implementing abstract public class NodeLevelAbstract<E extends NodeLevelEnum> implements NodeLevel<E>
delegates to instances of class A
that implements public interface NodeLevelEnum<E extends NodeLevelEnum>
. The last declaration should mean that instances of classes that implement NodeLevelEnum
can do something with instances of classes that implement NodeLevelEnum
.
Now, this is NodeLevelAbstract#getParent()
:
@Override
public E getParent() {
return this.getEnum().getParent();
}
Results in a compiler error (I use NetBeans 7.2, btw):
incompatible types
required: E
found: NodeLevelEnum
where E is a type-variable:
E extends NodeLevelEnum declared in class NodeLevelAbstract
To me, this means that a descendant of NodeLevelEnum
is required, but NodeLevelEnum
is found, which, given that the bound in Java Generics includes itself, sounds like absolute bollocks.
Why are these types incompatible? And is there any graceful way to do what I mean to do? Thanks in advance. =)
Update 1
Btw, NodeLevelEnum#getParent()
returns <E extends NodeLevelEnum>
, and not NodeLevelEnum
, which the error says it does.
Update 2
abstract public class NodeLevelAbstract<E extends NodeLevelEnum> implements
NodeLevel<E> {
protected E _enum;
@Override
public E getEnum() {
return this._enum;
}
@Override
public E getParent() {
return this.getEnum().getParent();
}
public static <E extends NodeLevelEnum<E>> E[] getEnumLineage(E _enum) {
ArrayList<E> ancestors = new ArrayList<>();
E currentEnum = _enum;
do {
ancestors.add(currentEnum);
currentEnum = currentEnum.getParent();
} while (currentEnum != null);
return (E[]) ancestors.toArray();
}
public static <E extends NodeLevelEnum<E>> HashMap<String, String>
getEnumLineageValueMap(
E _enum) {
HashMap<String, String> map = new HashMap<>();
for (E e : getEnumLineage(_enum)) {
map.put(e.getCode(), e.getValue());
}
return map;
}
}
public interface NodeLevel<E extends NodeLevelEnum> {
public E getEnum();
public E getParent();
}
public interface NodeLevelEnum<E extends NodeLevelEnum> {
public E getParent();
}
public interface FilestructureLevel<E extends NodeLevelEnum<E>> extends
NodeLevel<E> {
public String getPathPrefix();
}
public class FileLevel<E extends NodeLevelEnum<E>> extends NodeLevelAbstract<E>
implements FilestructureLevel<E> {
protected String _pathPrefix;
@Override
public String getPathPrefix() {
return this._pathPrefix;
}
public HashMap<String, String> getValueMap(Boolean withPath) {
return getEnumLineageValueMap(this.getEnum(), withPath);
}
public static <E extends NodeLevelEnum<E>> HashMap<String, String>
getEnumLineageValueMap(
E _enum) {
return getEnumLineageValueMap(_enum, false);
}
public static <E extends NodeLevelEnum<E>> HashMap<String, String>
getEnumLineageValueMap(
E _enum, Boolean withPath) {
HashMap<String, String> map = new HashMap<>();
FileLevelEnum[] lineage = (FileLevelEnum[]) getEnumLineage(_enum);
for (FileLevelEnum e : lineage) {
String value = !withPath ? e.getValue() : e.getPathPrefix()
+ e.getValue();
map.put(e.getCode(), value);
}
return map;
}
}