Java:检查命令行参数
我知道可以很容易地使用try/catch检查命令行参数是否为双精度 我正在寻找一种不使用昂贵的try/catch块来检查这一点的方法。我对Java相当陌生。我搜索了一些论坛,但没有找到任何与我的问题相关的东西Java:检查命令行参数,java,Java,我知道可以很容易地使用try/catch检查命令行参数是否为双精度 我正在寻找一种不使用昂贵的try/catch块来检查这一点的方法。我对Java相当陌生。我搜索了一些论坛,但没有找到任何与我的问题相关的东西 System.out.println(Double.parseDouble(args[1])); ^^这将导致错误。除了尝试/捕获之外,有人能告诉我如何进行数据验证以防止这种情况发生吗?假设args[1]是一个文本字符串。try-catch方法是普遍接受的方法,主要是因为一个有效的dou
System.out.println(Double.parseDouble(args[1]));
^^这将导致错误。除了尝试/捕获之外,有人能告诉我如何进行数据验证以防止这种情况发生吗?假设args[1]是一个文本字符串。try-
catch
方法是普遍接受的方法,主要是因为一个有效的double实际上可以有很多格式:
double a = 42.e10; // or 42.E10
double b = 42.f; // or 42.F
double c = 42.d; // or 42.D
double d = 010E010D;
double e = 0x1.fffffffffffffP+1023;
double f = 0x1.0p-1022;
所有这些都是有效的双精度数,可以通过parseDouble()
从字符串中解析Double.parseDouble(“NaN”)
和Double.parseDouble(“无限”)
也有效(尽管NaN
和Infinity
不是文本)。更不用说parseDouble()
还处理前导空格或尾随空格。所以我的答案是:不要!使用try
-catch
方法。可以构造一个正则表达式来匹配有效双精度格式的某些子集(甚至可能是全部),但我怀疑这实际上比捕获和处理NumberFormatException
更有效
完整的正则表达式实际上在以下文档中进行了解释: 为了避免对无效字符串调用此方法并引发
NumberFormatException
,可以使用下面的正则表达式来筛选输入字符串:
final String Digits = "(\\p{Digit}+)";
final String HexDigits = "(\\p{XDigit}+)";
// an exponent is 'e' or 'E' followed by an optionally
// signed decimal integer.
final String Exp = "[eE][+-]?"+Digits;
final String fpRegex =
("[\\x00-\\x20]*"+ // Optional leading "whitespace"
"[+-]?(" + // Optional sign character
"NaN|" + // "NaN" string
"Infinity|" + // "Infinity" string
// A decimal floating-point string representing a finite positive
// number without a leading sign has at most five basic pieces:
// Digits . Digits ExponentPart FloatTypeSuffix
//
// Since this method allows integer-only strings as input
// in addition to strings of floating-point literals, the
// two sub-patterns below are simplifications of the grammar
// productions from section 3.10.2 of
// The Java™ Language Specification.
// Digits ._opt Digits_opt ExponentPart_opt FloatTypeSuffix_opt
"((("+Digits+"(\\.)?("+Digits+"?)("+Exp+")?)|"+
// . Digits ExponentPart_opt FloatTypeSuffix_opt
"(\\.("+Digits+")("+Exp+")?)|"+
// Hexadecimal strings
"((" +
// 0[xX] HexDigits ._opt BinaryExponent FloatTypeSuffix_opt
"(0[xX]" + HexDigits + "(\\.)?)|" +
// 0[xX] HexDigits_opt . HexDigits BinaryExponent FloatTypeSuffix_opt
"(0[xX]" + HexDigits + "?(\\.)" + HexDigits + ")" +
")[pP][+-]?" + Digits + "))" +
"[fFdD]?))" +
"[\\x00-\\x20]*");// Optional trailing "whitespace"
if (Pattern.matches(fpRegex, myString))
Double.valueOf(myString); // Will not throw NumberFormatException
else {
// Perform suitable alternative action
}
正如您所看到的,这是一个令人讨厌的正则表达式。try-
catch
方法是普遍接受的方法,主要是因为一个有效的double实际上有很多格式:
double a = 42.e10; // or 42.E10
double b = 42.f; // or 42.F
double c = 42.d; // or 42.D
double d = 010E010D;
double e = 0x1.fffffffffffffP+1023;
double f = 0x1.0p-1022;
所有这些都是有效的双精度数,可以通过parseDouble()
从字符串中解析Double.parseDouble(“NaN”)
和Double.parseDouble(“无限”)
也有效(尽管NaN
和Infinity
不是文本)。更不用说parseDouble()
还处理前导空格或尾随空格。所以我的答案是:不要!使用try
-catch
方法。可以构造一个正则表达式来匹配有效双精度格式的某些子集(甚至可能是全部),但我怀疑这实际上比捕获和处理NumberFormatException
更有效
完整的正则表达式实际上在以下文档中进行了解释: 为了避免对无效字符串调用此方法并引发
NumberFormatException
,可以使用下面的正则表达式来筛选输入字符串:
final String Digits = "(\\p{Digit}+)";
final String HexDigits = "(\\p{XDigit}+)";
// an exponent is 'e' or 'E' followed by an optionally
// signed decimal integer.
final String Exp = "[eE][+-]?"+Digits;
final String fpRegex =
("[\\x00-\\x20]*"+ // Optional leading "whitespace"
"[+-]?(" + // Optional sign character
"NaN|" + // "NaN" string
"Infinity|" + // "Infinity" string
// A decimal floating-point string representing a finite positive
// number without a leading sign has at most five basic pieces:
// Digits . Digits ExponentPart FloatTypeSuffix
//
// Since this method allows integer-only strings as input
// in addition to strings of floating-point literals, the
// two sub-patterns below are simplifications of the grammar
// productions from section 3.10.2 of
// The Java™ Language Specification.
// Digits ._opt Digits_opt ExponentPart_opt FloatTypeSuffix_opt
"((("+Digits+"(\\.)?("+Digits+"?)("+Exp+")?)|"+
// . Digits ExponentPart_opt FloatTypeSuffix_opt
"(\\.("+Digits+")("+Exp+")?)|"+
// Hexadecimal strings
"((" +
// 0[xX] HexDigits ._opt BinaryExponent FloatTypeSuffix_opt
"(0[xX]" + HexDigits + "(\\.)?)|" +
// 0[xX] HexDigits_opt . HexDigits BinaryExponent FloatTypeSuffix_opt
"(0[xX]" + HexDigits + "?(\\.)" + HexDigits + ")" +
")[pP][+-]?" + Digits + "))" +
"[fFdD]?))" +
"[\\x00-\\x20]*");// Optional trailing "whitespace"
if (Pattern.matches(fpRegex, myString))
Double.valueOf(myString); // Will not throw NumberFormatException
else {
// Perform suitable alternative action
}
正如你所看到的,这是一个令人讨厌的正则表达式。正如评论员奥斯卡·洛佩兹所说,只需使用try/catch块和catch NumberFormatException。这是确保目标字符串是正确格式的double的正确方法,try/catch构造的潜在开销值得程序的正确性和清晰性
Double d=null;
试一试{
d=Double.parseDouble(args[1]);
}捕获(NumberFormatException nfe){
//待办事项
}
正如评论员奥斯卡·洛佩兹所说,只需使用try/catch块和catch NumberFormatException。这是确保目标字符串是正确格式的double的正确方法,try/catch构造的潜在开销值得程序的正确性和清晰性
Double d=null;
试一试{
d=Double.parseDouble(args[1]);
}捕获(NumberFormatException nfe){
//待办事项
}
Java没有现成的isDouble
或isNumeric
方法,但您可以自己编写:
public static boolean isDouble(String s) {
try {
Double.parseDouble(s);
} catch (NumberFormatException e) {
return false;
}
return true;
}
但是,double
有很多方法可以编写它:
- 23.2
- 23f
- 23e10
- 2_3 .4_5(不能用
解析)Double#parseDouble(字符串)
- 2_3 E1_0d(无法使用
进行分析)Double#parseDouble(字符串)
public static boolean isDoubleDigits(String s) {
return s.matches("\\d+(\\.\\d{1,2})?");
}
Java没有现成的
isDouble
或isNumeric
方法,但您可以自己编写:
public static boolean isDouble(String s) {
try {
Double.parseDouble(s);
} catch (NumberFormatException e) {
return false;
}
return true;
}
但是,double
有很多方法可以编写它:
- 23.2
- 23f
- 23e10
- 2_3 .4_5(不能用
解析)Double#parseDouble(字符串)
- 2_3 E1_0d(无法使用
进行分析)Double#parseDouble(字符串)
public static boolean isDoubleDigits(String s) {
return s.matches("\\d+(\\.\\d{1,2})?");
}
为什么不使用框架进行命令行输入验证?签出为什么不使用框架进行命令行输入验证?签出只需使用一个
try/catch NumberFormatException
。这不是很昂贵(谁告诉你的?)而且,确定什么是有效的double
值的验证规则对于实现来说可能非常复杂:您运行该语句多少次?这是一个被证实的瓶颈吗?如果没有,那么您肯定应该使用经过测试的真正的try/catch解决方案。记住:过早优化是万恶之源。像其他人一样使用try/catch。只需使用try/catch NumberFormatException
。这不是很昂贵(谁告诉你的?)而且,确定什么是有效的double
值的验证规则对于实现来说可能非常复杂:您运行该语句多少次?这是一个被证实的瓶颈吗?如果没有,那么您肯定应该使用经过测试的真正的try/catch解决方案。记住:过早优化是万恶之源。像其他人一样使用try/catch。
s实际上不适用于parseDouble()
,即使它们在Java 7的双文本中是有效的。
s实际上不适用于parseDouble()
,尽管它们在Java7的双文本中是有效的