Селективное возвращаемое значение Java Generics - PullRequest
4 голосов
/ 07 августа 2011

Я боролся с этим некоторое время и до сих пор не нашел ответа.В результате мой мозг несколько запутался, поэтому извините, если я совершил глупую ошибку.

Я пытаюсь реализовать типизированный анализатор INI, который будет анализировать этот тип файла:

[section1]
<int>intkey=0
<float>floatkey=0.0
<str>stringkey=test

[section2]
<float>x=1.0
<float>y=1.0
<float>z=0.0

При этом у меня есть центральный класс с именем Config, который обрабатывает основные операции чтения и записи.Один из методов Config называется get(String section, String key), который в идеале должен возвращать значение, соответствующее запрошенной паре ключ-ключ, например:

Config cfg = new Config("test.ini");
cfg.get("section2", "x"); // 1.0, not "1.0" or some Object that technically represents the float
cfg.get("section1", "intkey"); // 0
cfg.get("section1", "strkey"); // "test"

В настоящее время я использую enumдля обработки преобразования String в различные типы с помощью метода abstract, переопределяемого различными типами:

enum Type
{
  INTEGER ("int") {
    public Object parse(String value) {
      try
      {
        return Integer.parseInt(value);
      } catch (NumberFormatException e)
      {
        return null;
      }
    }
  },
  FLOAT ("float") {
    public Object parse(String value) {
      try
      {
        return Float.parseFloat(value);
      } catch (NumberFormatException e)
      {
        return null;
      }
    }
  },
  STRING ("str") {
    public Object parse(String value) {
      return value;
    }
  };

  public final String name;

  Type(String name)
  {
    this.name = name;
  }

  private static HashMap<String, Type> configMap = generateConfigMap();

  private static HashMap<String, Type> generateConfigMap()
  {
    HashMap<String, Type> map = new HashMap<String, Type>();
    for (Type type : Type.values())
      map.put(type.name, type);
    return map;
  }

  public static Type get(String name)
  {
    return configMap.get(name);
  }

  abstract public Object parse(String value);
}

К сожалению, parse(String value) возвращает объект и при его выходе из Config, требует приведения или подобного, и в идеале это было бы автономно.

Если я делаю это совершенно неправильно, и есть более гибкий или простой способ его кодирования, пожалуйста, дайте мне знать.Я открыт для предложений.Хотя я хотел бы знать, есть ли способ сделать это.Может быть с дженериками ...?

Примечание: я знаю, что мне не хватает импорта и тому подобного.Я здесь не поэтому пишу.

Ответы [ 2 ]

1 голос
/ 07 августа 2011

Вот в чем дело. Если код, который вызывает config.get(), не знает, какой тип ожидать, вы не сможете вернуть ничего, кроме Object, так как вызывающий код не знает, чего ожидать. Конечно, вам придется сыграть.

Теперь, если вы хотите спроектировать Config таким образом, чтобы вызывающий знал , какой тип он запрашивал, это становится немного проще. Самый простой подход - сделать что-то вроде этого:

public class Config {
    public int getInt(String a, String b) {
        return ((Integer)get(a, b)).intValue();
    } 
}

Но до тех пор, пока вызывающий абонент не знает, чего ожидать, вы действительно ничего не выиграете, избегая приведения.

1 голос
/ 07 августа 2011

Если вы хотите вернуть тип объекта в зависимости от того, что вы получаете, вы можете сделать это:

public <T extends MyObject> T myMethod(Class<T> type) {
    return type.cast(myObj);
}
...