Java 泛型返回类型

43
我想编写一个方法,可以接受类型参数(或者方法可以从中推断出类型),并返回该类型的值,以便我不必强制转换返回类型。
这是一个方法:
public Object doIt(Object param){
    if(param instanceof String){
        return "string";
    }else if(param instanceof Integer){
        return 1;
    }else{
        return null;
    }
}

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

如何编写此方法以接受类型参数并返回此类型?


3
一个重要的问题是你是否会一直使用String和int。如果是这样的话,你不需要一个通用的方法。你需要两个方法,一个接受并返回int,另一个接受并返回String。 - Jonathon Faust
4个回答

83

如果您不想使用特定的接口来处理这些内容,您可以通过以下方式使用通用方法:

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

11

从这里开始:

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

8
简短的回答是不要使用泛型。一旦涉及到instanceof,通常泛型就不是正确的答案。相反,应该使用重载方法来解决问题。
public String doIt(String param){
    return "string";
}

public Integer doIt(Integer param){
    return 1;
}

public Object doIt(Object param){
    return null;
}

4
六年后……话虽如此,如果声明的类型是“Object”,这将无法正常工作,因为方法重载是根据变量的声明类型在编译时完成的。 - Powerlord
如果你有Object var = "Bacon";,那么尽管它是一个String,也会调用doIt(Object param) - Powerlord

0
我建议您不要使用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);
    }
}

从你的例子中,你可以使用重载而不是使用通用方法,因为返回类型不用于动态绑定。 - Jack
1
当然,我只是试图给出尽可能接近发布的代码的答案。我认为我回答中发布的代码是一个可怕的想法,尽管它实现了所需的功能,但我不会使用它 :-) - TofuBeer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接