Java中的泛型方法模式

Java中的泛型方法模式,java,generics,design-patterns,Java,Generics,Design Patterns,我对Java泛型非常陌生,花了大量时间寻找合适的解决方案(如果有的话) 我正在尝试设计适配器来处理特定类型的类的对象。如下所述,CAdapter类仅处理“CClass”对象。我试图提供一个抽象的通用适配器来处理大部分工作(非常类似于LinkedList之类的Java集合)。然后,我为需要支持的每种类型提供一个具体的适配器实现 // Classes public interface AInterface { public String toString(); } public class

我对Java泛型非常陌生,花了大量时间寻找合适的解决方案(如果有的话)

我正在尝试设计适配器来处理特定类型的类的对象。如下所述,CAdapter类仅处理“CClass”对象。我试图提供一个抽象的通用适配器来处理大部分工作(非常类似于LinkedList之类的Java集合)。然后,我为需要支持的每种类型提供一个具体的适配器实现

// Classes

public interface AInterface {
  public String toString();
}

public class BClass extends AInterface  {
  public String toString() { return "BClass "; }
}

public class CClass extends AInterface  {
  public String toString() { return "CClass"; }
}

// Adapters

public interface AdapterInterface<T extends AInterface> {
  public T getInterface();
}

public class BAdapter implements AdapterInterface<BClass> {
  private BClass aInterface = null;
  public BClass getInterface() { return aInterface; }
}

public class CAdapter implements AdapterInterface<CClass> {
  private CClass aInterface = null;
  public CClass getInterface() { return aInterface; }
}
//类
公共接口接口{
公共字符串toString();
}
公共类b类扩展了AInterface{
公共字符串toString(){return“BClass”;}
}
公共类CClass扩展了AInterface{
公共字符串toString(){return“CClass”;}
}
//适配器
公共接口适配器接口{
公共T getInterface();
}
公共类BAdapter实现AdapterInterface{
私有b类aInterface=null;
公共b类getInterface(){return aInterface;}
}
公共类CAdapter实现AdapterInterface{
私有类aInterface=null;
公共类getInterface(){return aInterface;}
}
首先,我读到为这样一个通用适配器提供一个具体的实现是不受欢迎的(关于上帝杀死一只小猫的事情)!也许有人能在这方面做些扩展

其次,我遇到了一个问题:动态实例化适配器,而没有Java编译器。例如,我有以下方法:

public <T extends AInterface> AdapterInterface<T> getAdapter(String type) {
  AdapterInterface<T> result = null;
  if (type.equals("C") {
    result = new CAdapter();
  }
  return result;
}
public adapter接口getAdapter(字符串类型){
AdapterInterface结果=空;
if(类型等于(“C”){
结果=新的CAdapter();
}
返回结果;
}
当然,编译器会抱怨CAdapter不匹配。给定任何类型的AInterface对象,我希望能够加载正确的适配器并对其进行适当的处理。为了实现这一点,我无法理解工厂模式


任何想法都将不胜感激。

这里不要使用泛型,协变(或逆变,永远记不清哪个是哪个)返回类型似乎可以满足您的要求:

interface AdapterInterface {
    public AInterface getInterface();
}

class BAdapter implements AdapterInterface {
    private BClass aInterface = null;

    public BClass getInterface() {
        return aInterface;
    }
}

class CAdapter implements AdapterInterface {
    private CClass aInterface = null;

    public CClass getInterface() {
        return aInterface;
    }
}

public AdapterInterface getAdapter(String type) {
    AdapterInterface result = null;
    if (type.equals("C")) {
        result = new CAdapter();
    }
    return result;
}
除非在您没有提到的接口中还有其他方法。下面的类也是泛型的:

public
AdapterInterface<? extends AInterface> getAdapter(String type) {
    if (type.equals("C")) {
        return new CAdapter();
    } else {
        // …
    }
}
公共

AdapterInterface我的回答有点多余,但是:

任何带有“我的来电者知道这种类型是什么,但我不知道”意思的东西

因为这段代码不能假设t是C类

事实上,没有强制转换是无法做到这一点的(声明方法wild carred只是意味着您需要将结果强制转换到您调用的位置)。强制转换是您告诉编译器“我知道您无法知道这是什么,没关系:我知道。相信我。冷静。”。是的,您会得到警告。没关系


泛型不能消除所有类型转换,但它们允许您只执行一次。您不需要到处使用类型转换,而只需要在您(编码员)确信您正在玩类型游戏的某个位置使用它们。所有其余的代码,使用您刚刚创建的适配器的suff,都可以安全运行使用泛型类型调用k。

是否调用foo.getAdapter(C)?否则T是未绑定的。更常见的模式是公共适配器接口getAdapter(类clazz);你必须给杀小猫的部分提供一些上下文。如果我们不知道互联网上的某个人说了什么,我们就不能告诉你他是对的还是错的。@Nialscorva这并不重要。类型系统无法证明你是否提供了类型标记。当方法签名类似于e
T获取whateveroftype(类类型)
,因为
Class.newInstance()
Class.cast()
等。如果您不处理给定类的实例,它们就没有用处。@Nialscorva,也就是说,如果您可以将
AdapterInterface.class
传递给方法参数,那么这里会有所帮助,但如果没有超类型标记,这是不可能的。(我认为他们实际上对解决这个问题没有帮助,不是静态地使代码类型安全。)当我在
适配器接口中看到这样的代码时,我要做的第一件事就是打开浏览器,感谢您的输入。在您的答案和下面的答案之间(PaulMurrayCbr)我想我终于掌握了如何处理Java泛型——特别是在使用factory设计模式时。我将在factory中执行一次强制转换并抑制警告,理解泛型(至少在Java 5/6中)无法消除所有强制转换。@MichaelCronk说得对。关于Java泛型的许多SO问题实际上都是问如何实现他所考虑的类型约束,只是为了找出为什么不可能。但是,你可以而且应该做的是尽量避免未经检查的强制转换(强制转换为类型参数和参数化类型),方法是将它们替换为
Class.cast()
和其他运行时类型检查。或者将它们尽可能狭窄地封装在您知道是正确的代码中,即使类型系统无法验证它。感谢您的回答。我很感激您对其进行了非常清楚的解释。我偷了一句话“我的调用者知道这种类型是什么,但我不知道”,这比我想解释的要清楚得多。
AdapterInterface<T> result = null;
result = new CAdapter();