0

这是我用来保存父母的通用儿童列表的代码的简化版本。请原谅我不得不手动重写而不是复制过去,没有办法从有问题的机器上复制。

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 版。

附言。我不知道为什么我的代码示例的格式如此丑陋。如果有人可以修复它或告诉我如何修复它,我将不胜感激。我以前从来没有遇到过这个问题...

4

2 回答 2

1

这里需要两种解决方案。

根据 Louis 的评论,添加了一个泛型 ? getChildren 的 MyObject 定义的参数修复了我在原始问题中提到的错误消息...

这给我留下了关于在 getChildren 行的返回行上显示的不可转换类型的原始错误消息。这是我尝试参数化模型一直试图解决的真正问题,这就是为什么我认为问题在于未能投射。

原来错误施放失败。maven 使用的编译器(我认为是 javac)似乎坚持抛出错误,因为我将其转换为更具体的集合类型。实际上,我有一个可以包含 MyObject 的任何暗示的集合,即使它不是 childType,我也将作为一组 childType 返回。我理解抱怨,我没有得到的是为什么它会在我被投了简短的回答,javac只是坚持在这里抛出一个错误,而eclipse编译器(正确地,在我看来)只返回一个警告并继续运行。这就是为什么我在运行maven时只看到错误,Eclipse编译器编译它没有问题,只有当我运行 maven 时,我才最终将编译器转换为 javac。可能是错的。

一旦我确认我对情况的理解是正确的,即编译器只是在抱怨一些我认为它不应该而不是真正的错误的东西,我就投入了自己的技巧来满足编译器的要求。以下是对这两个问题的修复:

  public <childType extends MyObject<?>> Set<childType> getChildren(MyObject<childType> parent)
  {

     return (Set<childType>) (Set) store.get(parent);
  }

你看到一个双重演员。第一次强制转换使 javaC “忘记”我的 Set 具有 MyObject 的参数化类型。然后它将允许我将集合转换为特定的参数化类型 Set,因为它不“知道”我是从不太精确的参数化类型 Set 转换的。当然,从 Set 转换意味着从不精确的 set 定义(我可以在其中有一个 Enum 或 Float)转换为我的特定参数化类型;但是javaC对此很好。是的,它在最多应该是警告的内容上引发错误(包括丢弃注释以忽略警告)的事实仍然困扰着我......

于 2013-05-29T21:19:56.817 回答
1

好的,双重转换,这很可怕,但它有效:我在 Eclipse 中编译代码时遇到了类似的问题,但在 maven 下没有:这使它在两种情况下都有效(它是一个 javafx 绑定)currentElement.bind((ObservableValue<? extends Element>) (ObservableValue) treeItem.valueProperty());:。我将模型绑定到 treeItem 屏幕值。

于 2016-07-11T13:13:23.573 回答