Source code: import java.util.Map; import java.util.HashMap; import java.io.File; public class CommandLineProcessor { public static final String ARG_PREFIX1 = "--"; public static final String ARG_PREFIX2 = "//"; protected Map m_optionExtractors = new HashMap(); protected FileOption m_fileSetter = null; protected int m_fileIndex = 0; public void registerOption (String optionName, Option handler) { addExtractor(optionName, new OptionExtractor(handler)); } public void registerOption (String optionName, StringOption handler) { addExtractor(optionName, new StringOptionExtractor(handler)); } public void registerFiles (FileOption handler) { m_fileSetter = handler; } public void registerOption (String optionName, IntOption handler) { addExtractor(optionName, new IntOptionExtractor(handler)); } public void execute (String[] args) { boolean optionsAllowed = true; int argIndex = 0; while (argIndex < args.length) { String arg = args[argIndex++]; if (optionsAllowed) { if (ARG_PREFIX1.equals(arg) || ARG_PREFIX2.equals(arg)) { optionsAllowed = false; continue; } String optionName; if (arg.startsWith(ARG_PREFIX1)) { optionName = arg.substring(ARG_PREFIX1.length()); } else if (arg.startsWith(ARG_PREFIX2)) { optionName = arg.substring(ARG_PREFIX2.length()); } else { optionName = null; } if (optionName == null) { setFile(arg); } else { Extractor extractor = (Extractor) m_optionExtractors.get(optionName); if (extractor == null) { throw new Exception("Unexpected option '" + optionName + "'"); } argIndex = extractor.execute(optionName, args, argIndex); } } else { setFile(arg); } } } protected void setFile (String value) { if (m_fileSetter == null) { throw new Exception("Unexpected file name: '" + value + "'"); } m_fileSetter.execute(++m_fileIndex, new File(value)); } protected void addExtractor (String optionName, Extractor extractor) { if (m_optionExtractors.containsKey(optionName)) { throw new Exception("Duplicated option name: '" + optionName + "'"); } m_optionExtractors.put(optionName, extractor); } public static class Exception extends java.lang.RuntimeException { public Exception (String message) { super(message); } public Exception (String message, Throwable nested) { super(message,nested); } } public interface Option { void execute (String option) throws Exception; } public interface StringOption { void execute (String option, String value) throws Exception; } public interface IntOption { void execute (String option, int value) throws Exception; } public interface FileOption { void execute (int fileNo, File value) throws Exception; } protected abstract class Extractor { public abstract int execute (String optionName, String[] args, int argIndex) throws Exception; protected String getArg (String optionName, String[] args, int argIndex, String errorMessage) { if (argIndex >= args.length) { throw newException(optionName, errorMessage); } return args[argIndex]; } protected Exception newException (String optionName, String errorMessage) { return new Exception("Invalid option '" + optionName + "': " + errorMessage); } } protected class OptionExtractor extends Extractor { protected Option m_handler; public OptionExtractor (Option handler) { m_handler = handler; } public int execute (String optionName, String[] args, int argIndex) { m_handler.execute(optionName); return argIndex; } } protected class StringOptionExtractor extends Extractor { protected StringOption m_handler; public StringOptionExtractor (StringOption handler) { m_handler = handler; } public int execute (String optionName, String[] args, int argIndex) { m_handler.execute(optionName, getArg(optionName, args, argIndex, "string value expected")); return argIndex + 1; } } protected class IntOptionExtractor extends Extractor { protected IntOption m_handler; public IntOptionExtractor (IntOption handler) { m_handler = handler; } public int execute (String optionName, String[] args, int argIndex) { String textValue = getArg(optionName, args, argIndex, "integer value expected"); int value; try { value = Integer.parseInt(textValue); } catch (Throwable t) { throw newException(optionName, "Invalid int argument"); } m_handler.execute(optionName, value); return argIndex + 1; } } } Sample application: import java.io.File; public class Test { public static void main (String[] args) throws Exception { final DummyFtpCopyUtility ftpCopy = new DummyFtpCopyUtility(); CommandLineProcessor clp = new CommandLineProcessor(); clp.registerOption("append", new CommandLineProcessor.Option() { public void execute (String option) { ftpCopy.appendMode = true; } }); clp.registerOption("host", new CommandLineProcessor.StringOption() { public void execute (String option, String value) { ftpCopy.host = value; } }); clp.registerOption("maxSize", new CommandLineProcessor.IntOption() { public void execute (String option, int value) { ftpCopy.maxFileSize = value; } }); clp.registerFiles(new CommandLineProcessor.FileOption() { public void execute (int fileNo, File value) { if (fileNo > 1) { throw new CommandLineProcessor.Exception("Too many files specified. Extra file: '" + value + "'"); } ftpCopy.sourceFile = value; } }); clp.execute(args); ftpCopy.copy(); } public static class DummyFtpCopyUtility { protected boolean appendMode; protected String host; protected int maxFileSize = 0; protected File sourceFile; public void copy() { if (sourceFile == null || host == null) { System.out.println("Host and source file must be specified"); } else { System.out.println("About to copy " + sourceFile + " to " + host); if (appendMode) { System.out.println("Append mode enabled"); } if (maxFileSize > 0) { System.out.println("Max file size: " + maxFileSize); } } } } } Sample command lines: java -cp . Test --host localhost Foobar.txt java -cp . Test --host localhost Foobar.txt --append java -cp . Test --host localhost Foobar.txt --append --maxSize 1024 java -cp . Test --host localhost --append --maxSize 1024 -- --Foo--