开发者

Java Generics Selective Return Value

I've been struggling with this for a while and have yet to find an answer. As a result, my brain is somewhat muddled, so pardon me if I make a dumb mistake.

I'm trying to implement a typed INI parser, that will parse this kind of file:

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

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

In doing so, I have a central class named Config, which handles the basic reading and writing operations. One of the methods of Config is called get(String secti开发者_JAVA百科on, String key), which ideally would return a value appropriate for the requested section-key pair, like so:

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"

I'm currently using an enum to handle the conversion of the String to various types, with an abstract method overridden by the different types:

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

Unfortunately, parse(String value) returns an Object, and when passed out of Config, requires a cast or similar, and ideally this would be self-contained.

If I'm going about this completely wrong and there's a more flexible or simple way to code it, please let me know. I'm open to suggestions. Though I would like to know if there's a way to do this. Maybe with generics...?

Note: I know I'm missing imports and the like. That's not why I'm posting here.


Here's the thing. If the code that calls config.get() doesn't know what type to expect, you can't possibly return anything other than Object since the calling code doesn't know what to expect. Of course you'll have to cast.

Now, if you wanted to design Config in a way that the caller did know what type it was asking for, than that becomes a bit easier. The easiest approach then is to do something like this:

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

But until the caller knows what to expect, you really gain nothing from avoiding casts.


If you want to return a a type of object depending on what you get you can do this:

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜