0

From time to time I'm in a situation where I need to convert String values to objects. And often I end up with a custom method.

Here's an example:

@Nullable
public static Object valueOf(Class pParamType, String pValue)
{
  if (pValue == null) return null;
  if ("null".equals(pValue)) return null;

  if (String.class.equals(pParamType)) return pValue;
  if (Number.class.equals(pParamType)) return Double.valueOf(pValue);
  if (Long.class.equals(pParamType) || Long.TYPE.equals(pParamType)) return Long.valueOf(pValue);
  if (Double.class.equals(pParamType) || Double.TYPE.equals(pParamType)) return Double.valueOf(pValue);
  if (Integer.class.equals(pParamType) || Integer.TYPE.equals(pParamType)) return Integer.valueOf(pValue);
  if (Byte.class.equals(pParamType) || Byte.TYPE.equals(pParamType)) return Byte.valueOf(pValue);
  if (Short.class.equals(pParamType) || Short.TYPE.equals(pParamType)) return Short.valueOf(pValue);
  if (Float.class.equals(pParamType) || Float.TYPE.equals(pParamType)) return Float.valueOf(pValue);

  if (Date.class.equals(pParamType))
  {
    try
    {
      return Formatter.parse(pValue, DATE_PATTERN);
    }
    catch (Exception e)
    {
      throw new IllegalArgumentException("Illegal date format");
    }
  }

  if (Boolean.class.equals(pParamType) || Boolean.TYPE.equals(pParamType))
  {
    return Boolean.valueOf(pValue);
  }

  throw new IllegalArgumentException("Parameters of type [" + pParamType.getName() + "] are not supported");
}

I do realize that it's impossible to convert to just any object. But most java.lang classes do have a valueOf method in place

But I hate to repeat myself, and I have the feeling that there should be something out there that does the same thing already, and probably even covers more.

My question is:

Does the jdk offer a similar utility class or method in the java framework ? Alternatively what do other frameworks offer ? (e.g. apache commons, spring, guava, ...)

5
  • Where do you get that String from? Commented Jun 28, 2017 at 9:17
  • @Tom Could be a webpage, could be from an xml file, or a http request, or a csv file, from a database, ... I have encountered the same problem in many places. Commented Jun 28, 2017 at 9:17
  • And you're doing that conversion manually, because? There are already frameworks to parse CSV files into Java Models, or Table row or parse XML files. Commented Jun 28, 2017 at 9:20
  • @Tom, True, but those frameworks didn't exist 20 years ago. Forget the CSV, let's pretend it's for an unmarshaller for a custom file format then. Commented Jun 28, 2017 at 9:26
  • There's no general purpose String to Object functionality. It's requirements like these that gave birth to XML and the likes (e.g. protobuf). Java being very careful about type safety, there's no automatic coercion like you'd get in something like Javascript. In the standard classes. I'm sure there are libraries for these purposes, but it's up to you to find them. Commented Jun 28, 2017 at 9:29

1 Answer 1

2

Using reflection you can try to find a constructor with String argument and invoke the constructor

public static void main(String[] args) throws Exception{
    System.out.println(valueOf(String.class, ""));
    System.out.println(valueOf(Long.class, "1"));
    System.out.println(valueOf(Integer.class, "1"));
    System.out.println(valueOf(Byte.class, "1"));
    System.out.println(valueOf(Short.class, "1"));
    System.out.println(valueOf(Double.class, "1.1"));
    System.out.println(valueOf(Float.class, "1.1"));
    System.out.println(valueOf(Boolean.class, "true"));
}

public static Object valueOf(Class pParamType, String pValue) throws Exception
{

    if (pValue == null) return null;
    if ("null".equals(pValue)) return null;

    Constructor constructor = pParamType.getConstructor(String.class);
    if (constructor!=null) {
        return constructor.newInstance(pValue);
    }
    //... keep the logic for Date
    throw new IllegalArgumentException("Parameters of type [" + pParamType.getName() + "] are not supported");
}
Sign up to request clarification or add additional context in comments.

3 Comments

It's hard to write it both compact and efficient. (e.g. in your code example, the use of constructors is a trade-off between compact-code and efficiency. For efficiency, you should be using the valueOf methods, because they use caching.) - That's why I think this code belongs in a framework. What I mean is: Apache commons has tons of big ugly methods, they don't seem to mind adding big ugly methods. And I don't mind using utility classes that hide big-ugly-code for me. (e.g. org.apache.commons.lang.StringEscapeUtils)
(Well, could also use reflection to check if there's a valueOf method, but in general reflection has its price too) Your answer does have a contribution, thanks.
Of course reflection code is much slower. If it's critical use original code.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.