java语言基础-类型运算细节
代码一:
public class varDemo
{
public static void main(String[] args)
{
byte a2;
a2=3+4;
System.out.println(a2);
}
}
运行结果:
到目前为止没问题,OK,我现在把代码改一下
代码二:
public class varDemo
{
public static void main(String[] args)
{
byte a=3;
byte a1=4;
byte a2;
a2=a+a1;
System.out.println(a2);
}
}
(编译前想着这应该和上面的运行结果一样,因为a2是byte型,a和a1也是byte型,编译和运行应该完全OK.....)
结果.......
运行结果:
WTF???
怎么报错了?再回去看代码,还是不知道哪里出了问题......
OK,言归正传,我们来分析一下哪里出了问题:
首先我们观察第一段代码和第二段代码的不同之处
通过比较,我们发现,a2都是byte型变量,而不同之处在a2右边的东东。第一段代码右边是两个常量:3和4,而第二段代码右边是两个变量:a和a1(尽管它们已经被赋了值,但它仍然有可能被改变,因此他们的值是不确定的,所以编译器无法判断a和a1的取值,(a和a1的值有可能会超出byte类型的最大或最小范围,)因此,编译器报错:有可能造成精度流失)。
所以我们可以得出一个结论:如果赋值号(=)右边是变量,编译器无法判断变量的取值,因此不能赋值给左边,所以编译器报错。
接下来我们看这段代码:
代码三:
public class varDemo
{
public static void main(String[] args)
{
byte a=3;
byte a1=4;
//byte a2;
int a2;
a2=a+a1;
System.out.println(a2);
}
}
这段代码和第二段代码的区别在于,a2由byte型变为int型,赋值号右边的a和a1仍然是byte型的变量。让我们看一看它能不能通过编译并成功运行呢
编译和运行结果:
没问题,成功通过编译和运行。
为什么赋值号右边同样是byte型变量,代码二报错而代码三成功通过编译和运行呢?
原因分析:
代码二的赋值号左边的a2也同右边一样是byte型,因此右边的两个byte型变量相加很有可能超出byte型的范围,会造成精度流失。
而代码三的赋值号左边的a2是int型,无论右边的两个byte型变量取什么值都不会超出a2的范围,因此成功通过编译。
马不停蹄......
再来看看下面一段代码:
代码四:
public class varDemo
{
public static void main(String[] args)
{
int x;
int x1=80;
int x2=98;
x=x1+x2;
System.out.println(x);
}
}
在这段代码中,x,x1,x2均为int型变量。(类似于代码二中a,a1,a2均为byte型变量)
但......
运行结果:
成功通过编译并运行!
原因:在计算机中,对整数的运算,运算的最终结果都仍然是整数(默认int型),用默认的int类型接收整数类型完全可以。因此可以通过编译。
但,有人要问了,就像代码二一样,如果右边的两个int型变量相加超过了int型的范围怎么办。OK,让我们来看一看这种情况:
代码五:
public class varDemo
{
public static void main(String[] args)
{
int x;
int x1=Integer.MAX_VALUE; //求int型变量的最大值
int x2=98;
x=x1+x2;
System.out.println(x);
}
}
运行结果:
果不其然,真的超出了int型的最大范围,至于为什么会是负数,是因为,右边两个变量的值相加已经超出了int型的范围了(-2^32 ~ 2^32-1),超出了32位,再向前进位,但赋值号左边的x是int型,最多只能取到32位,因此,系统自动地强行把高位数(大于32位)抛弃掉,因此第32位的数一定是1,而只有负数的最高位数才是1,所以,最终显示的是一个负数。
注:本人初学Java,若分析有什么错误的话,还望大家能够体谅并指出!谢谢!