Java 什么是;“可能的有损转换”;我的意思是,我如何修复它?
新的Java程序员经常被编译错误消息弄糊涂,例如: “不兼容类型:可能从double转换为int” 对于这一行代码:Java 什么是;“可能的有损转换”;我的意思是,我如何修复它?,java,compiler-errors,Java,Compiler Errors,新的Java程序员经常被编译错误消息弄糊涂,例如: “不兼容类型:可能从double转换为int” 对于这一行代码: int squareRoot = Math.sqrt(i); 一般来说,“可能的有损转换”错误消息是什么意思?如何修复它?首先,这是一个编译错误。如果您在运行时在异常消息中看到它,那是因为您运行的程序存在编译错误1 信息的一般形式如下: “不兼容类型:从到的可能有损转换” 其中和都是基本数字类型;i、 e.byte、char、short、int、long、float或doubl
int squareRoot = Math.sqrt(i);
一般来说,“可能的有损转换”错误消息是什么意思?如何修复它?首先,这是一个编译错误。如果您在运行时在异常消息中看到它,那是因为您运行的程序存在编译错误1 信息的一般形式如下: “不兼容类型:从
到
的可能有损转换”
其中
和
都是基本数字类型;i、 e.byte
、char
、short
、int
、long
、float
或double
中的一种
当代码尝试从
到
进行隐式转换时,会发生此错误,但转换可能有损
在问题中的示例中:
int squareRoot = Math.sqrt(i);
sqrt
方法产生一个double
,但是从double
到int
的转换可能有损
“潜在损耗”是什么意思?
让我们来看几个例子
long
转换为int
可能是一种有损转换,因为有long
值没有相应的int
值。例如,任何大于2^31-1的long
值都太大,无法表示为int
。同样,任何小于-2^31的数字都太小
int
转换为long
不是有损转换,因为每个int
值都有相应的long
值
float
转换为long
可能是一种有损转换,因为float
值太大或太小,无法表示为long
值
long
转换为float
不是有损转换,因为每个long
值都有相应的float
值。(转换后的值可能不太精确,但“丢失”并不意味着……在这种情况下。)
到short
或byte
char
到char
或byte
short
到int
,byte
或short
char
到long
,byte
,short
或char
int
到float
,byte
,short
,char
或int
long
todouble
,byte
,short
,char
,int
或long
float
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
。(转换将截断,而不是四舍五入。)
那么这个呢
byte b = (int) 512;
这将导致b
获取值0
。从较大的int类型转换为较小的int类型是通过屏蔽掉高阶位来完成的,而512
的低阶8位都是零
简而言之,您不应该简单地添加类型转换,因为它可能不适合您的应用程序
相反,您需要理解为什么代码需要进行转换:
- 发生这种情况是因为您在代码中犯了其他错误吗
是否应该是另一种类型,以便此处不需要有损转换- 如果有必要进行转换,则无提示有损转换是否意味着typecast将执行正确的行为
- 或者您的代码是否应该执行一些范围检查,并通过抛出异常来处理不正确/意外的值
for (double d = 0; d < 10.0; d += 1.0) {
System.out.println(array[d]); // <<-- possible lossy conversion
}
这是前一个问题的变体,解决方案是相同的。区别在于根本原因是Java数组被限制为32位索引。如果您想要一个包含231-1个以上元素的“类似数组”的数据结构,那么您需要定义或找到一个类来实现它
方法或构造函数调用中的“可能有损转换”
考虑这一点:
public class User {
String name;
short age;
int height;
public User(String name, short age, int height) {
this.name = name;
this.age = age;
this.height = height;
}
public static void main(String[] args) {
User user1 = new User("Dan", 20, 190);
}
}
int a = 21;
byte b1 = a; // <<-- possible lossy conversion
byte b2 = 21; // OK
使用Java 11编译上述内容可以得到以下结果:
$ javac -Xdiags:verbose User.java
User.java:20: error: constructor User in class User cannot be applied to given types;
User user1 = new User("Dan", 20, 190);
^
required: String,short,int
found: String,int,int
reason: argument mismatch; possible lossy conversion from int to short
1 error
问题在于,文本20
是int
,构造函数中的相应参数被声明为short
。将int
转换为short
是有损的
分配文字时的“可能有损转换”
考虑这一点:
public class User {
String name;
short age;
int height;
public User(String name, short age, int height) {
this.name = name;
this.age = age;
this.height = height;
}
public static void main(String[] args) {
User user1 = new User("Dan", 20, 190);
}
}
int a = 21;
byte b1 = a; // <<-- possible lossy conversion
byte b2 = 21; // OK
给出一个编译错误
1-例如,EclipseIDE有一个选项,允许您忽略编译错误并运行代码。如果选择此选项,IDE的编译器将创建一个
.class
文件,在该文件中,出现错误的方法将在调用时引发未检查的异常。异常消息将提到编译错误消息。对于更有用的“特定情况”有什么建议吗?我正在寻找一些例子,其中根本原因是对Java语言的一些明显的误解。。。这还没有涵盖。您没有提到的一个用例是数组初始化。例如,int[]a={23L}代码>或长l=23;int[]a={l}代码>