web-dev-qa-db-fra.com

Java type de retour générique

Je voudrais écrire une méthode qui peut accepter un paramètre de type (ou quoi que la méthode puisse déterminer le type à partir de) et renvoyer une valeur de ce type afin que je n'ai pas à transtyper le type de retour.

Voici une méthode:

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

Lorsque j'appelle cette méthode et que je lui transmets une chaîne, même si je sais que le type de retour sera une chaîne, je dois transtyper l'objet de retour. Ceci est similaire au paramètre int.

Comment dois-je écrire cette méthode pour accepter un paramètre de type et retourner ce type?

39
Colby77

si vous ne voulez pas avoir une interface spécifique pour gérer ce genre de choses, vous pouvez utiliser une méthode générique de cette manière:

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

Gardez à l'esprit que de cette façon, le compilateur ne sait rien du type que vous prévoyez d'utiliser à l'intérieur de cette méthode, vous devez donc utiliser un type lié, par exemple:

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

Mais vous devez être sûr d'avoir besoin d'une méthode générique, cela signifie que l'implémentation de doIt sera la même pour tous les types avec lesquels vous prévoyez de l'utiliser. Sinon, si chaque implémentation est différente, il suffit de surcharger les méthodes, cela fonctionnera correctement car le type de retour n'est pas utilisé pour la liaison dynamique:

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

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

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

Commencez par ceci:

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

La réponse courte est non. Dès que instanceof s'implique, les génériques sont généralement la mauvaise réponse. Utilisez plutôt des méthodes surchargées:

public String doIt(String param){
    return "string";
}

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

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

Je vous exhorte à [~ # ~] pas [~ # ~] utilisez instanceof, mais ce code fait ce que vous vouloir:

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);
    }
}
0
TofuBeer