Java 设计类/接口以支持返回不同类型的方法

Java 设计类/接口以支持返回不同类型的方法,java,Java,我的课程如下 public interface ITest <T> { public Set<T> methodHere(); } public class test1 implements ITest<String> { Set<String> methodHere(){ return // Set of String } } public class test2 implements ITest<Inte

我的课程如下

public interface ITest <T>
{
   public Set<T> methodHere();
}

public class test1 implements ITest<String>
{
   Set<String> methodHere(){
      return // Set of String
   }
}

public class test2 implements ITest<Integer>
{
   Set<Integer> methodHere(){
     return // Set of Integer
   }
}

public class ITestFactory {
 public static ITest getInstance(int type) {
  if(type == 1) return new test1();
  else if(type == 2) return new test2();
 }
}
public class TestUser {
    public doSomething(int type) {
       ITest t = ITestFactory.getInstance(type);
       if(type == 1) Set<Integer> i = t.methodHere();
       else if(type == 2) Set<String> s = t.methodHere();
       ...
    }
}
公共接口测试
{
公共集methodHere();
}
公共类test1实现了ITest
{
Set methodHere(){
return//字符串集
}
}
公共类test2实现了ITest
{
Set methodHere(){
return//整数集
}
}
公共级ITestFactory{
公共静态ITest getInstance(int类型){
if(type==1)返回新的test1();
else if(type==2)返回新的test2();
}
}
公共类TestUser{
公共剂量测量(整数型){
ITest t=ITestFactory.getInstance(类型);
如果(type==1)集合i=t.methodHere();
如果(type==2)设置s=t.methodHere();
...
}
}
factory类中有一条警告,ITest被用作原始类型。我应该做什么修改来摆脱它

TestUser代码看起来很难看。我是否遗漏了一些非常基本的东西?我不想使用
Set

谢谢
Nayn

在您的情况下,对于泛型参数,实际上没有任何特定用途的有意义的替换,但是您可以向方法签名添加
,以消除警告


我看到的示例代码的一个更大的问题是,在命名类和方法时没有遵循规则。

调用getInstance时,不可能知道将返回哪种类型

但是,您可以将factory方法的签名更改为使用泛型:

public <A> ITest<A> getInstance(Class<A> type)
{

}
public ITest getInstance(类类型)
{
}

没有机会-除非取消警告本身。在Java中,通常不可能声明只具有不同返回类型的方法。使用泛型也没有“逃避”。返回不同类型的同名方法需要不同的参数签名(请参阅:重载)

如果查看相应的字节码,您会发现
MethodHere
将返回一个对象。这称为类型擦除。泛型参数仅由编译器用于检查/确保类型安全


一如既往-返回一个公共超类型,并让方法调用方确定对象类型(如在适配器模式中使用)。

您可以返回一个
ITest
以消除警告,但可能需要一个更强烈的类型aproach:

public class TestFactory {
   public static ITest<?> getInstance(int type) {
      if(type == 1) 
         return new test1();
      else if(type == 2) 
         return new test2();
      else
         throw new IllegalArgumentException("Unknown type");
   }

   public static <T> ITest<T> getInstance(Class<T> clazz) {
      if(clazz == String.class) 
         return new test1();
      else if(clazz == Integer.class) 
         return new test2();
      else 
         throw new IllegalArgumentException("Unknown type");
   }
}
公共类测试工厂{
公共静态ITest getInstance(int类型){
如果(类型==1)
返回新的test1();
else if(类型==2)
返回新的test2();
其他的
抛出新的IllegalArgumentException(“未知类型”);
}
公共静态ITest getInstance(类clazz){
if(clazz==String.class)
返回新的test1();
else if(clazz==Integer.class)
返回新的test2();
其他的
抛出新的IllegalArgumentException(“未知类型”);
}
}

这不会直接起作用,因为他使用
int
来指定类型。他当然可以用一对
实例的
检查来替换
int
。是的,显然实现需要更改。但真正的变化是调用方法需要知道将返回的类型。尽管这是一个很好的答案,@Thirler的评论“当调用getInstance时,不可能知道将返回哪种类型”让我重新思考我的设计。我没有使用泛型,而是创建了一个干净的类层次结构。