接口中方法的java泛型类型参数

She*_*jie 5 java generics inheritance interface

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

我有一个界面,如:

interface A<T>{
    public void query(T type);
}
Run Code Online (Sandbox Code Playgroud)

两个子类如:

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

public class C implements A<HashMap> {
    public void query(HashMap type);
}
Run Code Online (Sandbox Code Playgroud)

然后我有一个工厂类来生产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();
        } 
   }
}
Run Code Online (Sandbox Code Playgroud)

这个想法是客户端可以使用如下的接口,而不依赖于B,C,如:

A instance = AFactory.getType("B");
String a = "test";
instance.query(a); 
Run Code Online (Sandbox Code Playgroud)

我在这里遇到的问题是:eclipse在instance.query(a)行上给出了错误:

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

我认为问题是接口契约不知道查询应该期待String或HashMap.我只能想到解决这个问题的方法是,我必须将结果转换为:

B instance = (B)AFactory.getType("B");
String a = "test";
instance.query(a); 
Run Code Online (Sandbox Code Playgroud)

但是通过这样做,我将依赖于B而不仅仅是A(接口),这是我想在开始时避免的.知道如何在不依赖子类的情况下做到这一点(在本例中为B和C).

Sea*_*lly 6

正如欧内斯特所说,你需要投出返回的值 - 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();
    }
}
Run Code Online (Sandbox Code Playgroud)

那么你的调用代码可能如下所示:

A<String> instance = AFactory.getType(String.class);
String a = "test";
instance.query(a);
Run Code Online (Sandbox Code Playgroud)

如果你不能这样做,那么调用者getType()必须进行投射.