tags:

views:

165

answers:

4

Hi,

I'd like to write a method that can accept a type param (or whatever the method can figure out the type from) and return a value of this type so I don't have to cast the return type.

Here is a method:

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

When I call this method, and pass in it a String, even if I know the return type will be a String I have to cast the return Object. This is similar to the int param.

How shall I write this method to accept a type param, and return this type?

+5  A: 

Start with this:

public interface Command<T>
{
    T execute(T parameter);
}
duffymo
+4  A: 

if you don't want to have a specific interface to handle that stuff you can use a generic method in this way:

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

Mind that in this way the compiler doesn't know anything about the type that you plan to use inside that method, so you should use a bound type, for example:

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

But you should be sure that you need a generic method, that means that the implementation of doIt will be the same for all the types you are planning to use it with. Otherwise if every implementation is different just overload the methods, it will work fine since return type is not used for dynamic binding:

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

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

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

I would urge you to NOT use instanceof, however this code does what you want:

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);
    }
}
TofuBeer
from your example you could just use overloading instead of using a generic method, since return type are not used for dynamic binding..
Jack
of course, I was just trying to give the answer that was as close to the code posted as possible. I think the code posted in my answer is a terrible idea and I would not use it, despite it doing what is desired :-)
TofuBeer
+4  A: 

The short answer is don't. As soon as instanceof gets involved, Generics are usually the wrong answer. Use overloaded methods instead:

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

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

public Object doIt(Object param){
    return null;
}
R. Bemrose