Java 可能的精度损失;从字符串中提取字符

Java 可能的精度损失;从字符串中提取字符,java,type-conversion,Java,Type Conversion,我从用户那里得到一个字符串,然后做一些检查以确保它是有效的,下面是我一直在使用的代码 char digit= userInput.charAt(0) - '0'; 在我对另一个方法做了一些工作之前,这个方法一直工作得很好。我开始编译,从那时起一直收到一个“可能会丢失精度”的错误 我做错了什么?Java可能正在将用户输入.charAt(0)和'0'转换为不同的数据类型,然后再转换回来 在将结果存储为数字之前,请尝试将其显式转换为char: char digit = (char)(userInpu

我从用户那里得到一个字符串,然后做一些检查以确保它是有效的,下面是我一直在使用的代码

char digit= userInput.charAt(0) - '0';
在我对另一个方法做了一些工作之前,这个方法一直工作得很好。我开始编译,从那时起一直收到一个“可能会丢失精度”的错误


我做错了什么?

Java可能正在将
用户输入.charAt(0)
'0'
转换为不同的数据类型,然后再转换回来

在将结果存储为数字之前,请尝试将其显式转换为
char

char digit = (char)(userInput.charAt(0) - '0');

首先,您应该使用执行此操作的方法,而不是自行开发的解决方案,即检查有效性和获取值:

char c = ...
if (Character.isDigit(c)) {
  // it's a digit
}
int value = Character.digit(c, 10);
您收到此警告的原因如下所示:

当运算符应用二进制 数字升级到一对 操作数,每个操作数必须表示 数值类型的值,如下所示 规则使用加宽按顺序应用 转换()以转换 必要时的操作数:

  • 如果任一操作数的类型为双精度,则另一个操作数将转换为
    double
  • 否则,如果其中一个操作数的类型为
    float
    ,则转换另一个操作数 到
    浮动
  • 否则,如果其中一个操作数的类型为
    long
    ,则另一个操作数将转换为
    long
  • 否则,两个操作数都将转换为类型
    int
所以当你做减法运算时,两个参数都被提升到
int
s。结果是一个
int
。当您尝试将
int
分配给
char
时,可能会丢失精度(32位有符号到16位无符号)

另一种验证技术是使用正则表达式:

if (s.matches("\\d\\d-\\d\\d")) {
  // it's ##-##
}
或者,如果您需要抓取群组:

Pattern p = Pattern.compile("(\\d\\d)-(\\d\\d)");
Matcher m = p.matcher(s);
if (m.matches()) {
  System.out.println(m.group(1)); // first group
  System.out.println(m.group(1)); // second group
}

这与Java在与算术运算符一起使用时如何隐式转换操作数有关


userInput.charAt(0)
'0'
都属于
char
类型,但它们被隐式转换为整数进行运算(减法),因此当整数结果被分配给
char
时,Java将给出一个错误。

你真的应该使用cletus的答案,我给了他+1。但是,如果您真的想在代码中使用减法,则根本不应将结果存储在
字符中,因为结果可能是负数(例如,如果用户输入“”(空格))

int-digit=userInput.charAt(0)-“0”;
如果(数字<0 | |数字>9)
抛出新的IllegalArgumentException(“0处输入错误,必须介于0和9之间”);
当然,这也不应该有一个硬编码索引,除非您真的想这样做
检查该字符串的第一个位置。

问题是我正在检查以确保用户输入的字符串格式为DigitDigitDigitDigitDigit,如果它与此不匹配,或者数字超出了我要检查的范围,那么我想返回一个错误。@特洛伊为什么不使用一个正则表达式,比如说
\d\d-\d\d
,并测试用户输入的值?如果没有,则使用
Character.isDigit()
可以执行所需的验证。@Troy:
数字
必须指定一个值,它是基本类型。值是二进制的0吗?如果字符(0)是一个“0”,这是有意义的。即使正确地进行了减法运算,也会将字符值0、1、2…9减少为二进制0、1、2…9。“0”以下的任何值实际上都将变为负值,但char是无符号值。你试图做的是无效的,没有意义的。使用克莱特斯的建议。如果你真的想这样做,请看我的答案。
int digit = userInput.charAt(0) - '0';
if (digit < 0 || digit > 9)
    throw new IllegalArgumentException("Bad input at 0, must be between 0 and 9.");