什么是“可能的有损转换”?是什么意思,我该如何解决? [英] What does "possible lossy conversion" mean and how do I fix it?

查看:484
本文介绍了什么是“可能的有损转换”?是什么意思,我该如何解决?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

新的Java程序员经常对编译错误消息感到困惑,例如:

New Java programmers are often confused by compilation error messages like:


不兼容的类型:可能从double转换为int

"incompatible types: possible lossy conversion from double to int"

这行代码:

int squareRoot = Math.sqrt(i);

这个错误意味着什么,你如何解决?

What does this error mean, and how do you fix it?

推荐答案

首先,这是一个编译错误。如果您在运行时在异常消息中看到它,那是因为您运行了编译错误 1 的程序。

First of all, this is a compilation error. If you ever see it in an exception message at runtime, it is because you have have run a program with compilation errors1.

一般消息的形式是这样的:

The general form of the message is this:


不兼容的类型:从 < type1>可能的有损转换 < type2>

其中 < type1> < type2> 都是原始数字类型;即 byte char short int long float double

where <type1> and <type2> are both primitive numeric types; i.e. one of byte, char, short, int, long, float or double.

当您的代码尝试从 <$ c $进行隐式转换时,会发生此错误c>< type1> < type2> 但转换可能是有损

This error happens when your code attempts to do an implicit conversion from <type1> to <type2> but the conversion could be lossy.

在问题的示例中:

  int squareRoot = Math.sqrt(i);

sqrt 方法产生 double ,但是从 double int 的转换可能是有损的。

the sqrt method produces a double, but a conversion from double to int is potentially lossy.

好吧,看看几个例子。


  1. long 转换为 int 是一种潜在的有损转换,因为 long 值没有相应的 int 值。例如,大于2 ^ 31 - 1的任何 long 值太大而无法表示为 int 。同样,任何小于-2 ^ 31的数字都太小。

  1. A conversion of a long to an int is a potentially lossy conversion because there are long values that do not have a corresponding int value. For example, any long value that is greater than 2^31 - 1 is too large to be represented as an int. Similarly, any number less than -2^31 is too small.

转换 int long 不是有损转换,因为每个 int 值都有一个相应的 long value。

A conversion of an int to a long is NOT lossy conversion because every int value has a corresponding long value.

float 转换为 long 是一个潜在的有损转换,因为 float 值太大或太小而无法表示为 long 值。

A conversion of a float to an long is a potentially lossy conversion because there float values that are too large or too small to represent as long values.

long 转换为 float 不是有损转换,因为每个 long 值都有一个相应的 float 值。 (转换后的值可能不太精确,但损失并不意味着......在这种情况下。)

A conversion of an long to a float is NOT lossy conversion because every long value has a corresponding float value. (The converted value may be less precise, but "lossiness" doesn't mean that ... in this context.)

这些都是可能有损的转换:

These are all the conversions that are potentially lossy:


  • short to byte char

  • char 字节

  • int to byte short char

  • long to byte char int

  • float byte short char int long

  • double to byte short char int long float

  • short to byte or char
  • char to byte or short
  • int to byte, short or char
  • long to byte, short, char or int
  • float to byte, short, char, int or long
  • double to byte, short, char, int, long or float.

使编译错误消失的方法是添加类型转换。例如;

The way to make the compilation error go away is to add a typecast. For example;

  int i = 47;
  int squareRoot = Math.sqrt(i);         // compilation error!

变为

  int i = 47;
  int squareRoot = (int) Math.sqrt(i);   // no compilation error

但这真的是一个修复?考虑 47 的平方根是 6.8556546004 ...但是 squareRoot 将获得 6 的值。 (转换将截断,而不是舍入。)

But is that really a fix? Consider that the square root of 47 is 6.8556546004 ... but squareRoot will get the value 6. (The conversion will truncate, not round.)

那么这个怎么样?

  byte b = (int) 512;

这导致 b 获取值 0 。通过屏蔽高阶位来完成从较大的int类型转换为较小的int类型,并且 512 的低阶8位全部为零。

That results in b getting the value 0. Converting from a larger int type to a smaller int type is done by masking out the high order bits, and the low-order 8 bits of 512 are all zero.

简而言之,您不应该简单地添加类型转换,因为它可能无法为您的应用程序执行正确的

In short, you should not simply add a typecast, because it might not do the correct thing for your application.

相反,您需要了解代码需要进行转换的原因:

Instead, you need to understand why your code needs to do a conversion:


  • 是否发生这种情况是因为您在代码中犯了其他错误?

  • < type1> 是一个不同的类型,所以这里不需要有损转换?

  • 如果需要进行转换,那么无声有损转换是类型转换会做正确的行为吗?

  • 或者您的代码是否应该进行一些范围检查并通过抛出异常处理错误/意外值?

  • Is this happening because you have made some other mistake in your code?
  • Should the <type1> be a different type, so that a lossy conversion isn't needed here?
  • If a conversion is necessary, is the silent lossy conversion that the typecast will do the correct behavior?
  • Or should your code be doing some range checks and dealing with incorrect / unexpected values by throwing an exception?

订阅时可能出现有损转换。

"Possible lossy conversion" when subscripting.

第一个例子:

for (double d = 0; d < 10.0; d += 1.0) {
    System.out.println(array[d]);  // <<-- possible lossy conversion
}

这里的问题是数组索引值必须是 int 。所以 d 必须从 double 转换为 int 。通常,使用浮点值作为索引没有意义。有人认为Java数组的工作方式与(比如)Python字典相似,或者他们忽略了浮点运算通常不精确的事实。

The problem here is that array index value must be int. So d has to be converted from double to int. In general, using a floating point value as an index doesn't make sense. Either someone is under the impression that Java arrays work like (say) Python dictionaries, or they have overlooked the fact that floating-point arithmetic is often inexact.

解决方案是重写代码以避免使用浮点值作为数组索引。 (添加类型转换可能是一个不正确的解决方案。)

The solution is to rewrite the code to avoid using a floating point value as an array index. (Adding a type cast is probably an incorrect solution.)

第二个例子:

for (long l = 0; l < 10; l++) {
    System.out.println(array[l]);  // <<-- possible lossy conversion
}

这是一个变种上一个问题,解决方案是一样的。不同之处在于根本原因是Java数组仅限于32位索引。如果你想要一个数组类似数据结构,它有超过2个 31 - 1个元素,你需要定义或找到一个类来完成它。

This is a variation of the previous problem, and the solution is the same. The difference is that the root cause is that Java arrays are limited to 32 bit indexes. If you want an "array like" data structure which has more than 231 - 1 elements, you need to define or find a class to do it.

1 - 例如,Eclipse IDE有一个选项,允许您忽略编译错误并运行代码。如果选择此选项,IDE的编译器将创建一个 .class 文件,如果调用该方法,则带有错误的方法将抛出未经检查的异常。异常消息将提及编译错误消息。

1 - For instance, the Eclipse IDE has an option which allows you to ignore compilation errors and run the code anyway. If you select this, the IDE's compiler will create a .class file where the method with the error will throw an unchecked exception if it is called. The exception message will mention the compilation error message.

这篇关于什么是“可能的有损转换”?是什么意思,我该如何解决?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆