1

我有非标准问题。

假设我有一个类MyClass,我从命令行执行带有参数列表的类

[<key> <value>]

喜欢:

MyClass -key1 arg1 -key2 arg2 -key3 arg3 ... -keyN argN。

因此我的班级遵循将输入数据传递给文件的方法:

public class MyClass{

private static String arg1;
private static String arg2;
private static String arg3;
...
private static String argN;

private static void getArgs(String[] args) {
    for(int k=0; k<args.length; k=k+2){
        if(args[k].equals("-key1")){ 
            arg1 = args[k+1];                 
        }
        else if(args[k].equals("-key2")){ 
            arg2 = args[k+1];                 
        }   
        else if(args[k].equals("-key3")){ 
            arg3 = args[k+1];                 
        }

                    ...

        else if(args[k].equals("-keyN")){ 
            argN = args[k+1];                 
        }
    }   
}

我编写自动化程序,大约有 30-40 个MyClass,每个都有 10-30 个参数。

所有类都有相同的字段和不同的字段(50/50)。

我不喜欢private static void getArgs(String[] args)方法实现,似乎浪费时间。

我虽然在 Notepad++ 中编写了一些基于 Reg-ex 的脚本并生成 java 代码,但在我想问是否有人知道其他技术/技术来处理输入参数之前。

[编辑]

我想使用反射,例如:

for(int k=0; k<args.length; k=k+2){
 Field field = classInstance.getClass().getDeclaredField(args[k].substring(1));
 field.setAccessible(true);
 field.set(classInstance, args[k]);
}

谢谢,

4

4 回答 4

4

Commons CLI已经为这个问题提供了一个很好的解决方案。我建议使用它,因为它已经过很好的测试和使用。重新发明图书馆是没有意义的。

于 2013-08-11T13:38:21.533 回答
2

当需要提供的参数很少时,将运行时参数传递给 java 程序很方便。但不是在有大量参数要传递给程序的情况下。我建议您不要使用命令行参数来提供您的信息,而应该使用属性文件。对您有利的是,Properties文件还将数据保存在键值对中,这对您的要求更有意义。此外,使用 java Properties类从文件中读取值也非常方便。

如果您需要,您可以将属性文件名(带有完整路径)作为参数传递给您的 java 类。

于 2013-08-11T12:37:11.303 回答
1

老实说,我只是解析它们并将它们放在地图中。并在需要时使用常量键从地图中获取值:private static final String KEY_FIRSTKEY = "firstkey";.

所以我会简单地编写一个函数parseArgs来把所有东西都放在一个地图中。(也许这属于实用程序类)。这是一个简单的例子(没有异常处理)

  private static Map<String, String> parseArgs(String... pArgs)
  {
    if (pArgs == null) return null;

    Map<String, String> map = new HashMap<String, String>();
    String arg;
    String key;
    String value;
    for (int i = 0, iLength = pArgs.length; i < iLength; i += 2)
    {
      arg = pArgs[i];

      // GET KEY
      if (!arg.startsWith("-")) continue;
      key = arg.substring(1);

      // GET VALUE
      if ((i + 1) >= pArgs.length) break;
      value = pArgs[i + 1];

      // PUT IT IN MAP
      map.put(key, value);
    }
    return (map.isEmpty()) ? null : map;
  }

但是,如果您真的更喜欢将它们放在私有字段中。然后我建议之后使用一些反射将地图转换为字段。这是一个例子:

  private static void mapStaticFields(Map<String, String> pMap, Class pStaticFieldHolder)
          throws NoSuchFieldException
  {
    if (pMap == null) return;
    for (Map.Entry<String, String> entry : pMap.entrySet())
    {
      try
      {
        Field field = pStaticFieldHolder.getDeclaredField(entry.getKey());
        field.setAccessible(true);
        field.set(field, entry.getValue());
      }
      catch (IllegalAccessException iae)
      {
        // impossible
      }
    }
}

把它们放在一个例子中:

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

public class MainTest
{
  private static String key1;
  private static String key2;
  private static String key3;

  public static void main(String... pArgs)
  {
    try
    {
      Map<String, String> argMap = parseArgs(pArgs);
      mapStaticFields(argMap, MainTest.class);

      System.out.println(key1);
      System.out.println(key2);
      System.out.println(key3);
    }
    catch (Exception e)
    {
      e.printStackTrace();
    }
  }
}

从命令行调用它java MainTest -key1 val1 -key2 val2 -key3 val3 会产生以下输出:

val1
val2
val3

享受 !

于 2013-08-11T13:30:06.190 回答
0

从参数列表构建 Map 应该很简单:

Map<String, String> map = new HashMap<>();
for (i=0; i < args.length-1; i+=2) {
     map.put(args[i], args[i+1];
}

然后,您可以初始化您的参数,例如:

String arg1 = map.get("-key1");
...
于 2013-08-11T13:11:35.937 回答