Java泛型,使用原始类的方法

时间:2010-12-06 10:51:14

标签: java generics

我想要做的是,创建一个返回带有泛型参数的String的函数。然后我需要使用一个特定类的getName()方法(更好地解释代码)。

以下是代码:

protected StringBuilder createJSON(Collection<E> jsonData) {
        StringBuilder JSONBuilder = new StringBuilder();
        JSONBuilder.append("{\"options\":[");
        int count = jsonData.size();
        for(Object obj: jsonData) {
            count--;
            JSONBuilder.append("{\"label\":\"" + obj.getName() + "\",\"value\":\"" + obj.getName() + "\"}");
            if(count>0) {
                JSONBuilder.append(",");
            }
        }
        JSONBuilder.append("]}");

        return JSONBuilder;
    }

createJSON采用对象的泛型集合,问题是当我需要使用getName()时。我传递给这个函数的对象是com.opensymphony.user.UserManager和com.atlassian.jira.ComponentManager,两者都带有getName()方法。

4 个答案:

答案 0 :(得分:2)

这两个对象没有实现声明getName()方法的相同接口。您必须将对象强制转换为这两个类之一并调用该方法或使用反射。

答案 1 :(得分:2)

使用泛型实现此目的的唯一方法是添加一个接口,该接口将getName()定义到可出现在集合中的所有类,然后使用Collection<E extends IFace>(其中IFace是名称你的新界面)。

根据您指定的名称,我非常确定您无法改装两者的界面。

它为您提供了一个包装类:您必须将您的元素包装在两个实现接口的辅助类中,并将对getName()的调用委托给实际类(请参阅适配器或委托模式)。

答案 2 :(得分:2)

  

问题是我需要使用的时候   的getName()。我传递给的对象   这个功能是   com.opensymphony.user.UserManager和   com.atlassian.jira.ComponentManager,   两者都使用getName()方法。

你想要duck typing。 Java没有它。你运气不好

由于可能这些类没有使用您需要的方法实现接口而您无法更改它们,因此您可以选择:

  • 想出一些过度设计的设计模式
  • 务实忘记干净的OO设计,只需使用instanceof

答案 3 :(得分:2)

只有当引用的类/接口声明方法时,才可以调用object的方法。在你的情况下,你必须:

  1. 转换为ComponentManager或UserManager,然后调用getName()
  2. 定义您自己的interface Nameable { public String getName(); }使两个类都实现此接口。 现在您的方法的参数将是Collection<E extends Nameable> jsonData,因此您可以在不进行强制转换的情况下调用此方法。
  3. 使用反射:(