【问题标题】:How do I define the return type inside a Java generics method?如何在 Java 泛型方法中定义返回类型?
【发布时间】:2012-06-29 17:15:13
【问题描述】:

我有一个通用的方法,例如:

public static<T> T execute(...) {
    ...
}

如何定义方法体中的 T 类型?例如:

if (T == String) {
  // do something with strings
  // return string;
}
if (T == Bitmap) {
  // do something with bitmap
  // return bitmap;
}

我尝试了以下方法,但没有成功:

T par = null;
if(par instanceof String) {
    // do something with strings
    // return string;
}

我尝试像下面这样声明par,但这也不起作用。

T par = (T) null;
T par = (T) new Object();

【问题讨论】:

  • 如果你需要这样做,听起来你不想要泛型。
  • 也许您希望重载函数而不是泛型?有一个方法execute(String s) 和另一个execute(BitMap b)
  • 没有输入参数相同,重要的是返回值不同。
  • "我如何定义 T 是什么类型" 你没有定义 T 是什么。相反,调用者选择 T 是什么,您的方法必须能够使用任何选择的 T

标签: java generics instanceof


【解决方案1】:

你可能会这样做:

public static <T>  T execute(Class<T> t) {
    if(String.class == t) {

    }
}

【讨论】:

    【解决方案2】:

    如果您的代码仅支持一组离散的数据类型,则您不想使用泛型。正如原帖中的 cmets 所述,这种情况需要重载方法调用。

    例如,假设您支持字符串、整数和双精度,但您没有其他数据类型的特定逻辑。您将定义您的方法,例如:

    public static String execute(String s) { ... }
    public static Integer execute(Integer i) { ... }
    public static Double execute(Double d) { ... }
    public static Object execute(Object o) { ... }
    

    前三个方法将为您支持的三种离散数据类型定义逻辑,而最后一个方法将为您不支持的任何其他数据类型定义逻辑和/或错误处理。 (当然,这不包括非 int 或 double 类型的原语,但这只是一个示例。)

    泛型最初被添加到 Java 中以支持 Collection 确切地知道它包含什么。例如,这是一种通过将 List 声明为 List&lt;String&gt; 来保证 List 只包含字符串的方法。然后扩展了此功能,但保留了基本概念 - 保证如果您放入 X 类型的未知对象,即使您在编译时不知道 X 是什么,您也可以编写逻辑以获得相同的 X 类型出去。 (This article 读起来很有趣,如果过时了。)

    不是意味着它应该用于方法或类中应用的逻辑取决于输入的数据类型。它应该用在与传入数据类型无关的地方,并且相同的逻辑将一致地应用于未知数据类型X。所以如果你有不同的逻辑对于 String 而不是 Doubles,您不应该使用泛型。

    tl;博士: 由于原始帖子根据输入参数的数据类型指示了不同的逻辑,因此不适合使用泛型。应改用基于支持的数据类型重载execute 方法。

    【讨论】:

    • 我明白,但如果我需要的话:codepublic static String execute(String s) { ... } public static Integer execute(String s) { ... } public static Double execute (String s) { ... } public static Object execute(String s) { ... } code 一切都取决于字符串是什么。如果字符串是图像 URL,我想要获取 Bitmap 或 Drawable。如果字符串是 XML 或 JSON 的 URL,我想得到它。
    【解决方案3】:

    T 这里称为类型参数。

    //这里会在go()方法中定义T的类型

    public interface Comparable<T> { 
    
    
            public int compareTo(T t) {
    
               // do something...
    
             }
          }
    

    例如:

    我正在上课,我想根据歌曲的标题对歌曲进行排序。

    public class Song implements Comparable<Song> {
    
      private String title;
    
      public void compareTo(Song s) {
    
           title.compareTo(s.title());
    
        }
    
      public void setTitle(String s) {
    
        this.title = s;
    
       }
    
      public void getTitle() {
    
        return this.title;
       }
    
      public String toString() {
    
        return getTitle();
    
       }
    
     }
    

    【讨论】:

      【解决方案4】:

      如果您已经以这种方式在代码中拆分功能,并且输入相同,那么您可能会很好地使用不同的功能。所以而不是(使用 Jeshurun 的回答)

      public static <T>  T execute(Class<T> t) 
      {
        if(String.class == t) {
      
        }
      }
      
      BitMap b = execute(BitMap.class);
      

      你应该有

      public BitMap bitmapExecute(...)
      {
        commonWork();
        //do bitmap stuff
      }
      
      public String stringExecute(...)
      {
        commonWork();
        //do String stuff
      }
      
      BitMap b = bitmapExecute(...);
      String s = stringExecute(...);
      

      如果有一大块通用代码,只有一小部分因类型而异,您可以将该通用代码移至其自己的函数中。

      public someObject commonWork(...)
      {
        //Do common stuff
      }
      

      只要您在编译时决定类型,您就不必有 instanceof 块。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-07-11
        • 2016-12-24
        • 2011-05-11
        • 2015-05-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多