猿问

“可能的有损转换”意味着什么?我如何修复它?

“可能的有损转换”意味着什么?我如何修复它?

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

“不兼容类型:可能从双重到int的有损转换”

对于这一行代码:

int squareRoot = Math.sqrt(i);

一般来说,“可能的有损转换”错误消息意味着什么,以及如何修复它?


qq_花开花谢_0
浏览 508回答 2
2回答

繁星淼淼

首先,这是一个编译错误。如果您在运行时在异常消息中看到它,这是因为您运行了一个程序,其中包含编译错误。1.该信息的一般形式如下:“不兼容类型:可能从<type1>到<type2>"哪里<type1>和<type2>都是原始数字类型;即byte,&nbsp;char,&nbsp;short,&nbsp;int,&nbsp;long,&nbsp;float或double.当您的代码尝试执行隐式转换自<type1>到<type2>但转换可能是洛西.在问题的例子中:&nbsp;&nbsp;int&nbsp;squareRoot&nbsp;=&nbsp;Math.sqrt(i);这个sqrt方法生成一个double,但是从double到int可能会有损失。“潜在损失”是什么意思?好吧,让我们来看看几个例子。a转换为along转到int是潜在的有损转换,因为long值,这些值没有对应的int价值。例如,任何long大于2^31-1的值太大,不能将其表示为int..同样,任何小于-2^31的数字都太小了。转换int转到long不是有损转换,因为int值具有相应的long价值。a转换为afloat转到long是潜在的有损转换,因为float值太大或太小,不能表示为long价值。转换long转到float不是有损转换,因为long值具有相应的float价值。(转换值可能不太精确,但“价值”并不意味着.在这方面)这些都是潜在有损失的转换:short到byte或charchar到byte或shortint到byte,&nbsp;short或charlong到byte,&nbsp;short,&nbsp;char或intfloat到byte,&nbsp;short,&nbsp;char,&nbsp;int或longdouble到byte,&nbsp;short,&nbsp;char,&nbsp;int,&nbsp;long或float.如何纠正错误?使编译错误消失的方法是添加一个类型广播。例如;&nbsp;&nbsp;int&nbsp;i&nbsp;=&nbsp;47; &nbsp;&nbsp;int&nbsp;squareRoot&nbsp;=&nbsp;Math.sqrt(i);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;compilation&nbsp;error!成&nbsp;&nbsp;int&nbsp;i&nbsp;=&nbsp;47; &nbsp;&nbsp;int&nbsp;squareRoot&nbsp;=&nbsp;(int)&nbsp;Math.sqrt(i);&nbsp;&nbsp;&nbsp;//&nbsp;no&nbsp;compilation&nbsp;error但这真的是个解决办法吗?的平方根47是6.8556546004..但squareRoot会得到价值6..(转换将截断,而不是圆形。)那这个呢?&nbsp;&nbsp;byte&nbsp;b&nbsp;=&nbsp;(int)&nbsp;512;这会导致b求值0..从较大的int类型到较小的int类型的转换是通过屏蔽高阶位和低阶8位来完成的。512都是零。简而言之,您不应该简单地添加一个类型广播,因为它可能做不到正确的事情。为你的申请.相反,您需要理解为什么您的代码需要进行转换:这是因为您在代码中犯了其他错误吗?如果<type1>是一种不同的类型,这样这里就不需要有损耗的转换了吗?如果必须进行转换,则沉默类型转换会做正确的行为吗?或者您的代码是否应该通过抛出异常来进行范围检查并处理不正确/意外的值?订阅时“可能的有损转换”。第一个例子:for&nbsp;(double&nbsp;d&nbsp;=&nbsp;0;&nbsp;d&nbsp;<&nbsp;10.0;&nbsp;d&nbsp;+=&nbsp;1.0)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;System.out.println(array[d]);&nbsp;&nbsp;//&nbsp;<<--&nbsp;possible&nbsp;lossy&nbsp;conversion}这里的问题是数组索引值必须是int..所以d必须从double到int..通常,使用浮点值作为索引是没有意义的。要么有人认为Java数组像Python字典那样工作,要么他们忽略了浮点运算通常是不精确的事实。解决方案是重写代码,以避免将浮点值用作数组索引。(添加类型强制转换可能是不正确的解决方案。)第二个例子:for&nbsp;(long&nbsp;l&nbsp;=&nbsp;0;&nbsp;l&nbsp;<&nbsp;10;&nbsp;l++)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;System.out.println(array[l]);&nbsp;&nbsp;//&nbsp;<<--&nbsp;possible&nbsp;lossy&nbsp;conversion}这是前一个问题的一个变体,解决方案是一样的。区别在于,根本原因是Java数组仅限于32位索引。如果您想要一个“像数组一样”的数据结构,它有超过2的31-1元素,您需要定义或找到一个类来完成它。带有文字的“可能的有损转换”考虑到这一点:INT a=21;字节b1=a;/<-可能的有损转换字节b2=21;/OK怎么一回事?为什么一个版本是允许的,而另一个版本是不允许的?(毕竟他们“做”了同样的事情!)首先,JLS声明:21是类型为int..(没有byte或short(文字)因此,在这两种情况下,我们都要分配一个int转到byte.在第一种情况下,错误的原因是并非所有int值将适合于byte.在第二种情况下,编译器知道21是一个始终适合于byte.技术上的解释是赋值上下文,则允许执行*基元收缩转换。to a字节,焦耳or矮的if: &nbsp;- the value is the result of a compile time *constant expression* (which includes literals), and &nbsp;- the type of the expression is字节,矮的,焦耳or和-该值在“目标”类型中是可表示的(不丢失的)。请注意,这仅适用于赋值语句。因此:字节b4=新字节(21);/不正确提供编译错误,尽管编译器不会将其描述为“可能的有损转换”。(它会说没有匹配的构造函数。)例如,EclipseIDE有一个选项,允许您忽略编译错误并运行代码。如果选择此选项,IDE的编译器将创建一个.class文件,其中包含错误的方法如果被调用,将抛出未经检查的异常。异常消息将提到编译错误消息。

SMILET

对于更有用的“具体案例”,有什么建议吗?我正在寻找一些例子,其中的根本原因是对Java语言的一些明显的误解.这还没有包括在内。
随时随地看视频慕课网APP

相关分类

Java
我要回答