3

This questions is close to this, but there is a major difference.

May requirements:

(1) I want to generate a Java function with generic return value.

(2) The list of input parameters is always the same. (unlike in link above).

(3) The function shall know, which type of return parameter is expected.

My tries:

public  <T> T getProperty(String name)
    { 
        T value;
        try {
            if (T instanceof String) {value = (T) getStringProperty(name);}
            if (T instanceof Long) {value = (T) getLongProperty(name);}
            if (T instanceof Boolean) {value = (T) getBooleanProperty(name);}           
        } catch (Exception e) {
            LOGGER.error("error at getProperty", e);

        }
        return value;
    }

This it is not working, since no instance of T is generated. Trys with T value = new T(); also failed.

Any quick fixes? Or is this approach not recommended?

Community
  • 1
  • 1
BerndGit
  • 1,278
  • 2
  • 13
  • 39
  • 1
    Notwithstanding the fact that you can't use `instanceof`, this is a bad approach, because you could write `String stringProp = TheClass.getProperty("foo"); Integer integerProp = TheClass.getProperty("foo");`: only one of these can succeed, but it fails at runtime. The same applies to @Chriss' answer: `String stringProp = TheClass.getProperty(String.class, "foo"); Integer integerProp = TheClass.getProperty(Integer.class, "foo");` fails at runtime. – Andy Turner May 25 '16 at 07:24
  • This is not really a duplicate, and there's a valid answer to accomplish the OP's goal. – Jim Garrison May 25 '16 at 07:25

3 Answers3

4

What you want to do is not possible due to type erasure of generics at runtime. In other words <T> will be erased to Object in your case.

You can pass a Class-Object like this to describe the return type:

public  <T> T getProperty(Class<T> returnType,String name){
   if (returnType == String.class)
       return (T)stringProperty(name);
   [...]
}
Chriss
  • 4,148
  • 6
  • 30
  • 60
  • This works but be aware that it bypasses type safety in that `getProperty(String.class,"someName") will throw a runtime exception if the property `someName` is not of type `String`. – Jim Garrison May 25 '16 at 07:27
  • Yes, thanks. I'm aware that some type checking has to be done by myself, when using this function. – BerndGit May 25 '16 at 07:34
0

From the answer of this question and from Angelika Langer's Java Generics FAQ you will find that You can not check the type of generic T

So all you have to do is pass type parameter in your method or change your code design.

Pass type parameter:

public  <T> T getProperty(Class<T> returnType, String name){
    if (returnType == String.class)
        return (T)stringProperty(name);
    [...]
}

Or call the getStringProperty(), getLongProperty() etc methods directly instead of calling getProperty() generic method.

Community
  • 1
  • 1
Emdadul Sawon
  • 4,434
  • 2
  • 36
  • 41
0

You can do in this way : public static Object getValue(Object str){

     if(str instanceof String){
          return   str;
     } if(str instanceof Integer){
          return   str;
     } if(str instanceof Long){
          return   str;
     } if(str instanceof Double){
          return   str;
     } if(str instanceof Float){
          return   str;
     } if(str instanceof BigDecimal){
          return  str;
     }

     return null;
}

or public static T getValue(Object str){

     if(str instanceof String){
          return  (T) str;
     } if(str instanceof Integer){
          return  (T) str;
     } if(str instanceof Long){
          return  (T) str;
     } if(str instanceof Double){
          return  (T) str;
     } if(str instanceof Float){
          return  (T) str;
     } if(str instanceof BigDecimal){
          return  (T) str;
     }

     return null;
}
Arun
  • 1
  • 2
  • Welcome to SO. I got already a suitable answer by Chris already (see checkmark left to his answer). – BerndGit May 25 '16 at 10:05