以下代码完全符合预期:
import java.math.BigDecimal;
import java.util.Scanner;
public class Test2 {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
BigDecimal number = new BigDecimal("0");
System.out.print("Enter a number: ");
try {
number = new BigDecimal(input.next());
}
catch(Exception e) {
System.out.println("Not a number.");
}
System.out.println(number);
}
}
如果我按如下所示删除try catch块并将其替换为while循环,则它不会执行预期的操作:
import java.math.BigDecimal;
import java.util.Scanner;
public class Test {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.print("Enter a number: ");
while (!input.hasNextBigDecimal()) {
System.out.print("Not a number, try again: ");
input.next();
}
BigDecimal number = input.nextBigDecimal();
System.out.println(number);
}
}
这是我运行时的输出:java Test
C:\>java Test
Enter a number: 1,1
1.1
为什么会接受逗号,但打印句号?
如果我运行以下代码,它将输出:en_ZA
import java.util.Locale;
public class Test3 {
public static void main(String[] args) {
System.out.println(Locale.getDefault());
}
}
如以下链接所示,我的语言环境的小数点分隔符是句点:
http://www.localeplanet.com/java/en-ZA/index.html
请告知我要去哪里了。
编辑:
在进一步调查中,我发现以下内容: https://www.sadev.co.za/content/how-correctly-format-currency-south-africa
因此,语言环境在技术上确实使用逗号。介意:)
答案 0 :(得分:2)
Scanner.hasNextBigDecimal()
使用默认语言环境的分组和小数点分隔符(在您的语言环境中似乎是“。”用于分组,而“,”则是十进制)来验证下一个标记是否与decimalpattern
相匹配:
...
DecimalFormat df =
(DecimalFormat)NumberFormat.getNumberInstance(locale);
DecimalFormatSymbols dfs = DecimalFormatSymbols.getInstance(locale);
// These must be literalized to avoid collision with regex
// metacharacters such as dot or parenthesis
groupSeparator = "\\" + dfs.getGroupingSeparator();
decimalSeparator = "\\" + dfs.getDecimalSeparator();
...
这段代码来自Scanner
类,并在初始化scanner
实例时执行。然后在调用groupSeparator
时使用decimalSeparator
和Scanner.hasNextBigDecimal()
来检查下一个标记是否与十进制格式匹配。
new BigDecimal(String)
直接使用'。作为小数点分隔符。
因此,如果您想使用Scanner.hasNextBigDecimal()
和'。作为用户输入的小数点分隔符,则应使用Scanner
的{{1}}方法。您的代码保存如下:
useLocale(Locale)
该程序接受逗号作为有效输入,然后打印句点 作为小数点。
再次Scanner input = new Scanner(System.in);
input.useLocale(Locale.ENGLISH);
System.out.print("Enter a number: ");
while (!input.hasNextBigDecimal()) {
System.out.print("Not a number, try again: ");
input.next();
}
BigDecimal number = input.nextBigDecimal();
System.out.println(number);
的{{1}}方法将所有Scanner
替换为nextBigDecimal()
,将groupSeparator
替换为""
,然后调用'new BigDecimal (串)'。 decimalSeparator
类的代码段是:
"."
这就是为什么它接受Scanner
并打印private String processFloatToken(String token) {
String result = token.replaceAll(groupSeparator, "");
if (!decimalSeparator.equals("\\."))
result = result.replaceAll(decimalSeparator, ".");
的原因。