Разбор объектов из строки в Java - PullRequest
6 голосов
/ 07 января 2010

Я пытаюсь написать общий метод для анализа объектов из строк. Чтобы было ясно, у меня есть следующая не очень элегантная реализация:

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 ...

}

Есть ли лучший способ реализовать это?

Ответы [ 6 ]

12 голосов
/ 19 января 2010

Ваш метод может содержать одну строку кода:

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

Тестирование с разными классами:

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());

Выход:

Obj: 123; type: Integer
Obj: str; type: String
Obj: 123; type: BigDecimal
Obj: java.text.SimpleDateFormat@38d640; type: SimpleDateFormat
8 голосов
/ 07 января 2010

Я не уверен, что ты пытаешься сделать.Вот несколько разных предположений:

  • Вы хотите иметь возможность преобразовывать объект в строку и наоборот.

Вы должны обратить внимание на сериализацию.Я использую XStream , но writeObject и java.beans.XMLEncoder также работает.

  • Пользователь вводит текст, и вы хотитечтобы привести его к «правильному» типу, которых много.

Обычно это означает проблему со спецификацией пользователя.Что вы получаете от пользователя, и почему он может иметь столько разных типов?

В общем, вы хотите, чтобы тип был максимально широким: используйте double, если это числои String почти для всего остального.Затем создайте другие вещи из этой переменной.Но не передавайте тип: обычно тип должен быть очень очевидным.

3 голосов
/ 07 января 2010

Как насчет перечислений?

  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 голос
/ 07 января 2010

NumberUtils.createNumber(str) (от apache commons-lang)

Он решает, какой тип числа создать, поэтому вы не пропустите класс.

0 голосов
/ 19 января 2010

Чтобы преобразовать объект (в данном случае строку) в другой объект, вы можете использовать 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);
0 голосов
/ 07 января 2010

Если это ваши единственные типы примеров, то вы также можете сделать что-то вроде:

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

Дополнительная информация может предоставить лучшие ответы. Я был бы очень удивлен, если бы уже не было какого-либо служебного кода, соответствующего вашим спецификациям. Есть несколько способов решения этой проблемы в зависимости от фактических требований.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...