泛型示例不起作用?替代方案或建议?

时间:2010-07-21 16:11:30

标签: java generics

我使用以下代码收到此错误:

  

The method getItemProperty(capture#2-of ? extends GenericTest.Item) in the type GenericTest.BaseContainer<capture#2-of ? extends GenericTest.Item> is not applicable for the arguments (GenericTest.Item)

import org.junit.Test;

public class GenericTest {

public class Item {
    private String value;

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }
}

public class WordItem extends Item {

}

public abstract class BaseContainer<T extends Item> {
    public String getItemProperty(T item) {
        return item.getValue();
    }
}

public class Document extends BaseContainer<WordItem> {
}

public static class ContainerFactory {
  public static BaseContainer<? extends Item> getContainer(Item item) {
     return new GenericTest().new Document();
  }
}

@Test
public void theTest(){
    Item item = new WordItem();
    BaseContainer<? extends Item> container = ContainerFactory.getContainer(item);
    String str = container.getItemProperty(item); //this line does not compile
}
}

我正在使用带有jdk 1.6.0_16的Eclipse Helios。

2 个答案:

答案 0 :(得分:2)

我认为问题是containerBaseContainer<? extends Item>,即它是某些子类型Item的容器。但是,编译器无法确保所讨论的子类型实际上是Item本身。实际上它是WordItem,而不是Item。总体问题是您的通用参数用法不一致且完整。

我可以使用这些修改来编译代码:

public class Document<T extends Item> extends BaseContainer<T> {
}

public static class ContainerFactory {
  public static <T extends Item> BaseContainer<T> getContainer(T item) {
     return new Test().new Document<T>();
  }
}

@Test
public void theTest(){
    WordItem item = new WordItem();
    BaseContainer<WordItem> container = ContainerFactory.getContainer(item);
    String str = container.getItemProperty(item);
}

这与TrueSoft的建议不同之处在于,此处Document也是通用的 - 这可能不是您想要的(您没有提供任何关于此的信息),但至少在这种情况下{}内不需要不安全的强制转换{1}}。

答案 1 :(得分:1)

要摆脱错误,请将代码更改为:

public static class ContainerFactory {
  public static <T extends Item>BaseContainer<T> getContainer(Item item) {
     return (BaseContainer<T>) new GenericTest().new Document();
  }
}

@Test
public void theTest(){
    Item item = new WordItem();
    BaseContainer<Item> container = ContainerFactory.getContainer(item);
    String str = container.getItemProperty(item);
}