2010-12-06 49 views
1

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

下面是代码:

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()方法。

+0

...那么究竟什么是** **问题?什么不会发生应,或者发生了什么不应该? – 2010-12-06 10:54:44

回答

2

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

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

由于想必这些类不实现你需要的方法的接口,你不能改变它们,你的选择是:

  • 拿出一些overengineeded设计模式
  • 务实忘记干净的OO设计,只是使用instanceof
2

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

2

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

从您指定的名称中,我非常确定您无法对两个接口进行翻新。

这给你带来了一个包装类:你必须将你的元素包装在两个实现接口的helper类中,并将调用getName()委托给真实的类(请参阅适配器或委托模式)。

2

只有在引用它的类/接口声明方法时,才可以调用对象的方法。你的情况,你必须要么:

  1. 投地的ComponentManager或的UserManager,然后调用的getName()
  2. 定义自己的interface Nameable { public String getName(); }使这两个类来实现这个接口。 现在您的方法的参数将为Collection<E extends Nameable> jsonData,因此您将能够在不投射的情况下调用此方法。
  3. 使用反射:(