9

I am trying to write a general method to parse objects from strings. To be clear, I have the following not-so-elegant implementation:

public static Object parseObjectFromString(String s, Class class) throws Exception {
  String className = class.getSimpleName();
  if(className.equals("Integer")) {
    return Integer.parseInt(s);
  }
  else if(className.equals("Float")) {
    return Float.parseFloat(s);
  }
  else if ...

}

Is there a better way to implement this?

1
  • Please add the context in which you want to use the method. It would help to give a proper solution. Commented Jan 19, 2010 at 11:24

6 Answers 6

14

Your method can have a single line of code:

public static <T> T parseObjectFromString(String s, Class<T> clazz) throws Exception {
    return clazz.getConstructor(new Class[] {String.class }).newInstance(s);
}

Testing with different classes:

Object obj1 = parseObjectFromString("123", Integer.class);
System.out.println("Obj: " + obj1.toString() + "; type: " + obj1.getClass().getSimpleName());
BigDecimal obj2 = parseObjectFromString("123", BigDecimal.class);
System.out.println("Obj: " + obj2.toString() + "; type: " + obj2.getClass().getSimpleName());
Object obj3 = parseObjectFromString("str", String.class);
System.out.println("Obj: " + obj3.toString() + "; type: " + obj3.getClass().getSimpleName());
Object obj4 = parseObjectFromString("yyyy", SimpleDateFormat.class);
System.out.println("Obj: " + obj4.toString() + "; type: " + obj4.getClass().getSimpleName());

The output:

Obj: 123; type: Integer
Obj: str; type: String
Obj: 123; type: BigDecimal
Obj: java.text.SimpleDateFormat@38d640; type: SimpleDateFormat
Sign up to request clarification or add additional context in comments.

1 Comment

+1 was going to suggest roughly the same. They have all a constructor taking a String.
8

I'm not sure what you're trying to do. Here's a few different guesses:

  • You want to be able to convert an object to a string, and vice-versa.

You should look into serialization. I use XStream, but writeObject and java.beans.XMLEncoder also works.

  • The user enters text, and you want to coerce it to the "right" type, of which there are many.

Usually, this means a problem with the user specification. What are you receiving from the user, and why would it be able to be so many different kinds?

In general, you will want the type to be as broad as possible: use double if it's a number, and String for almost everything else. Then build other things from that variable. But don't pass in the type: usually, the type should be very obvious.

1 Comment

+1 - I suspect that the OP is trying to solve the wrong problem.
3

How about enums?

  public enum Types {

     INTEGER {
        @Override
        public Object parse(String s) { return Integer.parseInt(s); }
     },
     FLOAT {
        @Override
        public Object parse(String s) { return Float.parseFloat(s); } 
     }
     ...
     ;

     public abstract Object parse(String s);

     public static Object parseObjectFromString(String s, Class<?> cls)  {
        return valueOf(cls.getSimpleName().toUpperCase()).parse(s);
     }
  }

  public static void main(String[] args) {
     System.out.println(Types.parseObjectFromString("5", Integer.class));
  }

1 Comment

Dunno; +1 for type token. It might also be interesting to return Number and specify a bounded wildcard type, Class<? extends Number>.
1

NumberUtils.createNumber(str) (from apache commons-lang)

It decides what type of number to create, so you don't pass the class.

Comments

0

If those are your only types of examples, then you can also do something like:

Constructor ctor = Class.getConstructor( String.class ); 
return ctor.newInstance( s );

More information may provide for better answers. I'd be very much surprised if there isn't already some utility code out there that meets your specifications. There are a few ways to tackle this problem depending on the actual requirements.

Comments

0

To convert from an Object (here a String) to another one, you can use transmorph :

Transmorph transmorph = new Transmorph(new DefaultConverters());
float myFloat = transmorph.convert("55.2",Float.TYPE);

long[] longsArray = transmorph.convert(new Integer[] { 1, 2, 3, 4 }, long[].class);

Comments

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.