2012-04-17 157 views
4

中的方法我想在这里实现的是由子类来决定是否要将java.lang.String或java.util.HashMap作为参数传递给query()方法。接口只需要声称,子类必须实现查询方法,但我不关心什么类型的参数的子类希望在通过java泛型类型参数接口

我有一个像接口:

interface A<T>{ 
    public void query(T type); 
} 

两个子像:

public class B implements A<String> { 
    public void query(String type); 
} 

public class C implements A<HashMap> { 
    public void query(HashMap type); 
} 

然后,我有一个工厂类以产生B或C:

public class AFactory { 
    public static A<?> getType(String type) { 
     if(type.equals("B")){ 
      return new B(); 
     } else if(type.equals("C")) { 
      return new C(); 
     } 
    } 
} 

的想法是,客户端可以使用该接口,如下而不会对乙依赖性,C等:

A instance = AFactory.getType("B"); 
String a = "test"; 
instance.query(a); 

问题我这里是:日食给我误差上instance.query的线(a) :

类型A中的方法查询(capture#2 of?)不适用于参数(String)

我认为问题在于接口契约不知道查询应该期待String或HashMap。我只能想到解决这个问题的办法是,我要投像的结果:

B instance = (B)AFactory.getType("B"); 
String a = "test"; 
instance.query(a); 

但是通过这样做,我会对B的,而不是只A(接口)的依赖这是一件好事我想在开始时避免。任何想法如何我可以做到这一点,而不依赖于子类(在这种情况下,B和C)。

+0

编译器查看A实例并说“我需要T,而不是String”,但是你不告诉他T是什么。尽我所知。 – JMelnik 2012-04-17 13:22:59

+0

graet,gotcha,谢谢@JMelnik – Shengjie 2012-04-17 14:15:50

回答

5

正如欧内斯特所说,你需要投下返回值 - A<String>A<?>更具体。

如果你愿意改变工厂方法的签名,你可以使用仿制药,以避免投自己:

public static A<T> getType(Class<T> type) { 
    if (type.equals(String.class)) { 
     return new B(); 
    } else if (type.equals(HashMap.class)) { 
     return new C(); 
    } 
} 

然后调用代码看起来是这样的:

A<String> instance = AFactory.getType(String.class); 
String a = "test"; 
instance.query(a); 

如果你不能这样做,那么getType()的调用者将不得不施放。

+0

+1感谢您的留言,你的回答比我的好:) – 2012-04-17 13:52:15

1

您不必投射到B - 投到A<String>。这会给你query(String),但没有引入B到源:

@SuppressWarnings("unchecked") 
A<String> instance = (A<String>) AFactory.getType("B"); 
String a = "test"; 
instance.query(a); 

我加了注释@SuppressWarnings,因为你会得到没有它“不安全”的警告;你知道警告是虚假的,所以注释是可以的。