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