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

时间:2010-06-01 10:59:45

标签: 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<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();
       ...
    }
}

工厂类中有一个警告,即ITest用作原始类型。我应该做些什么修改才能摆脱它?

TestUser代码看起来很难看。我错过了非常基本的东西吗?我不想使用Set<?>

由于 Nayn

4 个答案:

答案 0 :(得分:3)

您可以返回ITest<?>以消除警告,但可能您需要更强烈的类型:

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");
   }
}

答案 1 :(得分:0)

在您的情况下,Generics参数没有任何有意义的替代品实际上具有任何特定用途,但是您可以在方法签名中添加<Object><?>来摆脱警告。

我看到的示例代码的更大问题是,在命名类和方法时,您没有关注JCC

答案 2 :(得分:0)

当你调用getInstance时,无法知道将返回哪种类型。

但是,您可以更改工厂方法的签名以使用泛型:

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

}

答案 3 :(得分:0)

没有机会 - 除了压制警告本身。在Java中,通常不可能声明只有不同返回类型的方法。使用泛型并没有“逃避”。具有相同名称且返回不同类型的方法需要不同的参数签名(参见:重载)。

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

与往常一样 - 返回一个公共超类型并让方法调用者确定对象类型(就像在适配器模式中使用的那样)。