[英]java generics type parameter for method in interface
what I want to achieve here is that It's up to the subclass to decide whether they want to pass java.lang.String or java.util.HashMap as parameter to query() method. 我想在这里实现的是由子类决定是否要将java.lang.String或java.util.HashMap作为参数传递给query()方法。 Interface just needs to claim that subclasses have to implement query method, but I don't care about what type of parameter subclasses want to pass in.
接口只需要声明子类必须实现查询方法,但我不关心什么类型的参数子类想要传入。
I have a interface like: 我有一个界面,如:
interface A<T>{
public void query(T type);
}
Two subclasses like: 两个子类如:
public class B implements A<String> {
public void query(String type);
}
public class C implements A<HashMap> {
public void query(HashMap type);
}
Then I have a factory class to produce B or C: 然后我有一个工厂类来生产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();
}
}
}
The idea is that the client can use the interface as below without having dependencies on B,C like: 这个想法是客户端可以使用如下的接口,而不依赖于B,C,如:
A instance = AFactory.getType("B");
String a = "test";
instance.query(a);
The problem I have here is: eclipse gives me error on the line of instance.query(a): 我在这里遇到的问题是:eclipse在instance.query(a)行上给出了错误:
The method query(capture#2-of ?) in the type A is not applicable for the arguments (String) . 类型A中的方法查询(捕获#2-of?)不适用于参数(String) 。
I think the problem is that the interface contract doesn't know the query should be expecting String or HashMap. 我认为问题是接口契约不知道查询应该期待String或HashMap。 The way I can only think of solve this is that, I have to cast the result like:
我只能想到解决这个问题的方法是,我必须将结果转换为:
B instance = (B)AFactory.getType("B");
String a = "test";
instance.query(a);
But by doing this, I would have the dependency on B instead of just A(the interface) which is something I wanted to avoid at the beginning. 但是通过这样做,我将依赖于B而不仅仅是A(接口),这是我想在开始时避免的。 Any idea how I can do this without having dependencies on the subclasses(in this case, B and C).
知道如何在不依赖子类的情况下做到这一点(在本例中为B和C)。
As Ernest says, you need to cast the returned value — A<String>
is more specific than A<?>
. 正如Ernest所说,你需要转换返回的值 -
A<String>
比A<?>
更具体。
If you're willing to change the signature of the factory method, you could use generics to avoid having to cast yourself: 如果您愿意更改工厂方法的签名,可以使用泛型来避免不得不自己投射:
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();
}
}
Then your calling code could look like this: 那么你的调用代码可能如下所示:
A<String> instance = AFactory.getType(String.class);
String a = "test";
instance.query(a);
If you can't do this then the caller of getType()
will have to cast. 如果你不能这样做,那么
getType()
的调用者必须进行getType()
转换。
You don't have to cast to B
-- cast to A<String>
. 您不必强制转换为
B
- 强制转换为A<String>
。 That will give you query(String)
, but without introducing B
into your source: 这将为您提供
query(String)
,但不会将B
引入您的源:
@SuppressWarnings("unchecked")
A<String> instance = (A<String>) AFactory.getType("B");
String a = "test";
instance.query(a);
I added the @SuppressWarnings
annotation because you'll get an "unsafe" warning without it; 我添加了
@SuppressWarnings
注释,因为如果没有它,你会得到一个“不安全”的警告; you know the warning to be spurious, so the annotation is OK. 你知道警告是虚假的,所以注释是可以的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.