将String args []转换为对象

时间:2017-11-25 08:32:27

标签: java arguments main

我需要解析命令行参数并将它们转换为Java对象。

我的命令行来运行Java .jar:

java -cp "combo.jar" com.ascurra.Main --time=3 --limit=5000 --initDate=2017-01-01.13:00:00

我需要将参数--time=3 --limit=5000 --initDate=2017-01-01.13:00:00转换为对象并将其保存到我的数据库中。

如何以优雅的方式做到这一点?

3 个答案:

答案 0 :(得分:1)

我创建了一个args数组的流,map来保留所需字符串的一部分,即:

String[] resultArray = Arrays.stream(args)
                             .map(s -> s.substring(s.indexOf("=") + 1))
                             .toArray(String[]::new);

数组现在应该包含:

[3, 5000, 2017-01-01.13:00:00]

在这种情况下,您可以索引到此数组,然后转换为所需的任何其他类型并填充您的自定义对象。

或者,由于只有3个参数,您可以完全跳过创建流,只需使用substring索引到数组中以保留所需的部分。但是,上面的方法更具适应性,就好像您要输入更多参数一样,在检索参数方面,您无需更改代码中的任何内容。

答案 1 :(得分:1)

首先,创建一个具有相应字段的类

class Entry {

    private int time;
    private int limit;
    private Date initDate;

    public Entry() {
    }

    public Date getInitDate() {
        return initDate;
    }

    public void setInitDate(Date initDate) {
        this.initDate = initDate;
    }

    public int getLimit() {
        return limit;
    }

    public void setLimit(int limit) {
        this.limit = limit;
    }

    public int getTime() {
        return time;
    }

    public void setTime(int time) {
        this.time = time;
    }

}

然后创建此类的对象并解析参数以设置值

public static void main(String[] args) {

    ArrayList<String> options = new ArrayList<>();
    for (String arg : args) {  // get the options from the arguments
        if (arg.startsWith("--")) {
            options.add(arg.replace("--", ""));
        }
    }
    Entry entry = new Entry();

    for (String option : options) {
        String[] pair = option.split("=");
        if (pair.length == 2) {
            if (pair[0].equals("time")) { // parse time option
                entry.setTime(Integer.parseInt(pair[1])); 
            } else if (pair[0].equals("limit")) { // parse limit option
                entry.setLimit(Integer.parseInt(pair[1]));
            } else if (pair[0].equals("initDate")) { // parse initDate option
                SimpleDateFormat sdf = new SimpleDateFormat(
                        "yyyy-MM-dd.HH:mm:ss");
                try {
                    entry.setInitDate(sdf.parse(pair[1]));
                } catch (ParseException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    System.out.println(entry.getLimit() + " , " + entry.getTime() + " , "
            + entry.getInitDate());
}

答案 2 :(得分:1)

  

如何以优雅的方式做到这一点?

这三个信息(--time=3 --limit=5000 --initDate=2017-01-01.13:00:00)作为主要类String[] args中的特定元素传递。
解析它们并不是一项复杂的任务(String.substring()或正则表达式可以完成这项工作) 但是一个好的解析器也应该不会被参数的顺序烦恼,并且还应该考虑在数据映射到特定类型作为日期或数字类型的过程中产生相关的调试信息。
最后,添加或删除支持的参数应该是简单和安全的,并且获得命令帮助也是可取的。

首先建议,如果您可以使用库,请不要重新发明轮子并使用 Apache Commons CLI或更好地使用简单易用的arg4j并避免使用样板代码。

如果你做不到,至少会激励你。

Apache Commons CLI示例

例如创建Option s(参数):

public static final String TIME_ARG = "time";
public static final String LIMIT_ARG = "limit";
...

Options options = new Options();   
options.addOption("t", TIME_ARG, true, "current time");
options.addOption("l", LIMIT_ARG, true, "limit of ...");
...

然后解析Options并检索它的值:

public static void main(String[] args) {

  ...
  try{
    CommandLineParser parser = new DefaultParser();
    CommandLine cmd = parser.parse(options, args);
    ...
    // then retrieve arguments
    Integer time = null;
    Integer limit = null;
    LocalDateTime localDateTime = null;

    String timeRaw = cmd.getOptionValue(TIME_ARG);
    if (timeRaw.matches("\\d*")) { 
       time = Integer.valueOf(timeRaw); 
    }
    ...and so for until you create your object to save 
    MyObj obj = new MyObj(time, limit, localDateTime);
    ...
   }
   catch(ParseException exp ) {
      System.out.println( "Unexpected exception:" + exp.getMessage() );
   }
}

args4j示例

args4j很容易使用。
此外,它提供了一些转换器(从String到特定类型),但不提供开箱即用的日期转换。
所以你应该创建自己的处理程序来做那个。例如。

在示例中,LocalDateTimeOptionHandler必须实现[OptionHandler][3]

import org.kohsuke.args4j.CmdLineException;
import org.kohsuke.args4j.CmdLineParser;
import org.kohsuke.args4j.Option;
import org.kohsuke.args4j.OptionHandlerFilter;

public class SampleMain {

    @Option(name = "--time", usage = "...")
    private Integer time;

    @Option(name = "--limit", usage = "..")
    private Integer limit;

    @Option(name="--initDate", handler=LocalDateTimeOptionHandler.class, usage="...")
    private LocalDateTime initDate;

    public static void main(String[] args) throws IOException {
       new SampleMain().doMain(args);
    }

    public void doMain(String[] args) throws IOException {
      CmdLineParser parser = new CmdLineParser(this);

      try {
        // parse the arguments.
        parser.parseArgument(args);        
       } catch (CmdLineException e) {
         System.err.println(e.getMessage());
         System.err.println("java SampleMain [options...] arguments...");
         parser.printUsage(System.err);
         System.err.println("  Example: java SampleMain" + parser.printExample(OptionHandlerFilter.ALL));
         return;
       }

      if (time != null)
        System.out.println("-time is set");

      if (limit != null)
        System.out.println("-limit is set");

      if (initDate != null)
        System.out.println("-initDate is set");

    }
 }