从类型中获取autobox类

时间:2013-04-09 19:49:28

标签: java reflection types autoboxing command-line-parsing

我知道这个问题可能看起来很愚蠢,因为我可以手动执行此操作。但我喜欢在一个地方(仅限一个地方)拥有所有选择。

我想通过使用虚拟选项类中的字段名称来设置程序的可用选项(使用commons-cli),以便我可以将值分配给该类的实例。

问题是我无法弄清楚如何获取对应于基本类型的类对象并检索相应的autobox类。

这是我想要工作的代码(除了没有这样的方法getAutoboxClass)

public class PlayGame {
    private static final Options opts = new Options();

    static {
        Field[] allOpts = MCTSOptions.class.getFields();
        for (Field f : allOpts) {
            opts.addOption(new Option(f.getName(), f.getName(), !f.getType()
                    .equals(Boolean.TYPE), f.getName()));
        }
    }

    public static void main(String[] args) throws IOException, ParseException,
            IllegalArgumentException, IllegalAccessException,
            InvocationTargetException, SecurityException, NoSuchMethodException {
        BasicParser bp = new BasicParser();
        CommandLine cl = bp.parse(opts, args);
        String[] remainArgs = cl.getArgs();

        MCTSOptions params = new MCTSOptions();
        for (Field f : MCTSOptions.class.getFields()) {
            String name = f.getName();
                if (f.getType().equals(Boolean.TYPE)) {
                    f.set(params, true);
                } else if (f.getType().equals(String.class)) {
                    f.set(params, cl.getOptionValue(name));
                } else {
                    String value = cl.getOptionValue(name);
                    Method m = f.getType().getAutoboxClass()
                            .getMethod("valueOf", String.class);
                    f.set(params, m.invoke(null, value));
                }
            }
        }
        //...
    }
}

MCTSOptions的样子:

public class MCTSOptions {
    public boolean searchOnSample = false;
    public double winOnlyMult = 0.5;
    public double firstExplorationConstant = 2;
    public double nextLearningRate = 0.1;
    public double nextExplorationConstant = 2;
    public boolean firstUsesSqrt = false;
    public boolean nextUsesSqrt = false;
    public long timeGiven = 5000L;
    public long seed = 1L;
}

(所以现在它只是长篇和双打,但将来我可能会添加其他类型)

2 个答案:

答案 0 :(得分:1)

为什么不直接使用对象(布尔值,长度等)而不是基元?

答案 1 :(得分:1)

没有内置方法可以做到。

这就是为什么,例如,Guava为此任务提供a helper method。在内部,它实现为基元和包装器之间的简单映射。