这是我用来保存父级子级通用列表的代码的简化版本。请原谅我必须手动重写此内容而不是复制过去,无法从存在问题的机器复制。
MyObject<childType extends MyObject> {}
public class Model{
HashMap<MyObject, Set<MyObject>> store= new HashMap<MyObject, Set<MyObject>>()
public <childType extends MyObject> Set<childType> getChildren(MyObject<childType> parent)
{
return (Set<childType>) store.get(parent);
}
public void <T extends MyObject<?>> addChild(MyObject<T> parent, T child){
Set<MyObject> childSet=store.get(parent);
if(childSet==null){
childSet=new Set<MyObject>();
store.put(parent, childSet);
}
childSet.add(child);
}
这在 Eclipse 中构建没有问题。但是,如果我清理类文件并运行 Maven 安装,则会出现以下错误:
the parameter childType is not within its bound
getChildren 的定义发生错误。尽管在对存储进行参数化并在调用存储的类中将其强制转换为 Set 之前,我之前遇到过不同但类似的问题。
我明白如果我没有进行强制转换,为什么通常会发生这种异常。让我困惑的是我正在选角。我不明白为什么它会抛出错误并停止编译,而不是像我所说的那样接受类型转换“相信我,这是对的”并继续前进。
如果重要的话,我相信我正在使用 mavin-compile-pluging 版本 1.6。
ps。我不知道为什么我的代码示例的格式如此难看。如果有人可以修复它或告诉我如何修复它,我将不胜感激。我以前从未遇到过这个问题...
最佳答案
这里需要两个解决方案。
根据路易斯的评论,添加一个通用的 ? getChildren 的 MyObject 定义的参数修复了我在原始问题中提到的错误消息...
这给我留下了有关不可转换类型的原始错误消息,该消息显示在 getChildren 行的返回行上。这是我一直试图对模型进行参数化尝试解决的真正问题,这就是为什么我认为问题在于无法转换。
事实证明,错误是转换失败。由于我转换为更具体的集合类型,maven 使用的编译器(我认为是 javac)似乎坚持抛出错误。实际上,我有一个集合,它可以包含 MyObject 的任何实现,即使它不是 childType,我将作为一组 childType 返回。我理解这个提示,我没有得到的是为什么它会在以下情况发生:我被投了。简短的回答,javac只是坚持在这里抛出一个错误,而eclipse编译器(在我看来是正确的)只返回一个警告并继续运行。这就是为什么我在运行maven、Eclipse编译器时只间歇性地看到错误编译它没有问题,只有当我运行 maven 时,我才最终将编译器切换到 javac。我认为,如果 javaC 实现仅仅因为它拒绝接受显式强制转换,那么这是糟糕且令人困惑的行为 可能是错误的。
一旦我确认我对情况的理解是正确的,即编译器只是提示一些我认为不应该而不是真正的错误,我就加入了自己的黑客来满足编译器的要求。以下是对这两个问题的修复:
public <childType extends MyObject<?>> Set<childType> getChildren(MyObject<childType> parent)
{
return (Set<childType>) (Set) store.get(parent);
}
您会看到布景中有双重 Actor 阵容。第一次转换使 javaC “忘记”我的 Set 有一个 MyObject 的参数化类型。然后,它将允许我将集合转换为特定的参数化类型的集合,因为它不“知道”我正在从不太精确的参数化类型的集合进行转换。当然,从 Set 进行转换意味着从集合的甚至不太精确的定义(我可以在其中有一个 Enum 或 Float)转换为我的特定参数化类型;但 javaC 对此很满意。是的,它在最多应该是警告的内容上抛出错误(包括丢弃表示忽略警告的注释),这一事实仍然让我烦恼......
关于java - 由于边界原因,maven 拒绝编译泛型类,即使在转换类之后也是如此,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16821045/