所以,我有 this public interface NodeLevel<E extends NodeLevelEnum>
,它有方法public E getParent()
和public E getEnum()
. 一个实现abstract public class NodeLevelAbstract<E extends NodeLevelEnum> implements NodeLevel<E>
委托到实现的类的A
实例public interface NodeLevelEnum<E extends NodeLevelEnum>
。最后一个声明应该意味着实现类的实例NodeLevelEnum
可以对实现类的实例做一些事情NodeLevelEnum
。
现在,这是NodeLevelAbstract#getParent()
:
@Override
public E getParent() {
return this.getEnum().getParent();
}
导致编译器错误(我使用 NetBeans 7.2,顺便说一句):
incompatible types
required: E
found: NodeLevelEnum
where E is a type-variable:
E extends NodeLevelEnum declared in class NodeLevelAbstract
对我来说,这意味着 的后代NodeLevelEnum
是必需的,但NodeLevelEnum
被发现了,鉴于 Java 泛型中的边界包括自身,这听起来像是胡说八道。
为什么这些类型不兼容?有什么优雅的方式来做我想做的事吗?提前致谢。=)
更新 1
顺便说一句,NodeLevelEnum#getParent()
返回<E extends NodeLevelEnum>
,而不是NodeLevelEnum
,错误说它确实如此。
更新 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;
}
}