【问题标题】:Java generic return typeJava 泛型返回类型
【发布时间】:2010-04-19 17:01:45
【问题描述】:

我想编写一个可以接受类型参数(或任何方法可以从中找出类型)并返回此类型的值的方法,因此我不必强制转换返回类型。

这是一个方法:

public Object doIt(Object param){
    if(param instanceof String){
        return "string";
    }else if(param instanceof Integer){
        return 1;
    }else{
        return null;
    }
}

当我调用这个方法并传入一个字符串时,即使我知道返回类型将是一个字符串,我也必须强制转换返回对象。这类似于 int 参数。

我应该如何编写这个方法来接受一个类型参数并返回这个类型?

【问题讨论】:

  • 一个重要的问题是你是否会一直使用 String 和 int。如果是这种情况,您不需要通用方法。您需要两种方法,一种接受并返回 int,另一种接受并返回 String。

标签: java generics


【解决方案1】:

如果你不想有一个特定的接口来处理这些东西,你可以通过这种方式使用泛型方法:

public <T> T mymethod(T type)
{
  return type;
}

请注意,通过这种方式编译器对您计划在该方法中使用的类型一无所知,因此您应该使用绑定类型,例如:

public <T extends YourType> T mymethod(T type)
{
  // now you can use YourType methods
  return type;
}

但是你应该确定你需要一个泛型方法,这意味着doIt 的实现对于你计划使用它的所有类型都是相同的。否则,如果每个实现都不同,只是重载方法,它会正常工作,因为返回类型不用于动态绑定:

public String my(String s)
{
  return s;
}

public int my(int s)
{
  return s;
}

int i = my(23);
String s = my("lol");

【讨论】:

    【解决方案2】:

    从这里开始:

    public interface Command<T>
    {
        T execute(T parameter);
    }
    

    【讨论】:

      【解决方案3】:

      简短的回答是不要。一旦instanceof 参与进来,泛型通常是错误的答案。改用重载方法:

      public String doIt(String param){
          return "string";
      }
      
      public Integer doIt(Integer param){
          return 1;
      }
      
      public Object doIt(Object param){
          return null;
      }
      

      【讨论】:

      • 6 年后...话虽如此,如果声明的类型是 Object,这将不起作用,因为方法重载是在编译时根据变量的声明类型完成的。
      • 即如果你有Object var = "Bacon";,那么尽管是StringdoIt(Object param) 会被调用。
      【解决方案4】:

      我会敦促您不要使用 instanceof,但是此代码可以满足您的要求:

      public class Main
      {
          public static void main(String[] args) 
          {
              final Main main;
              final String strVal;
              final Integer intVal;
              final Float   floatVal;
      
              main     = new Main();
              strVal   = main.doIt("Hello");
              intVal   = main.doIt(5);
              floatVal = main.doIt(5.0f);
      
              System.out.println(strVal);
              System.out.println(intVal);
              System.out.println(floatVal);
          }
      
          public <T> T doIt(final T thing)
          {
              T t;
      
              if(thing instanceof String)
              {
                  t = (T)"String";
              }
              else if (thing instanceof Integer)
              {
                  t = (T)Integer.valueOf(1);
              }
              else
              {
                  t = null;
              }
      
              return (t);
          }
      }
      

      【讨论】:

      • 从您的示例中,您可以只使用重载而不是使用泛型方法,因为返回类型不用于动态绑定..
      • 当然,我只是想给出尽可能接近发布代码的答案。我认为在我的答案中发布的代码是一个糟糕的主意,我不会使用它,尽管它做了想要的:-)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-08-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-10-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多