thingking in java 读书感悟
作者 :淮左白衣
写于2018年4月8日17:51:44
关于整数的默认类型,以及会产生的一些小问题
在java中,整数 默认是 int 类型,小数 默认是 double 类型 ;因此,在一些地方会造成一些错误;
- 比如下面的代码。在编译的时候,是报错的:
long num = 99999999999999; // error
原因:因为整数默认是int类型,但是 99999999999999 明显的超出了 int 的取值范围;因此,这里就会报错,我们需要在整数后面加上一个 L ,告诉编译器,这是一个 long 类型数字 ;
long num = 99999999999999L; // ok
- 下面的代码,我们思考下原因:
byte a = 127 ; // ok
byte b = -128 ; // ok
byte c = a + b ; // error
byte d = 3 + 5 ; // ok
byte e = 125 + 5 ; // error
byte f = (byte) (127 + 5); // ok
System.out.println(f); // output : -124
byte g = 8 ;
g = g + 10 ; //error
g += 10 ; // ok
你可能会有一些疑问:
byte a = 127 ; // 为什么代表 int 类型的整数,可以直接赋值给 byte
byte的取值范围: -128 ~ 127 ;我们一般向下转型的时候,会产生丢失进度的问题,但是,当我们使用明明确确的 整形常量: -128~127 ;将它们赋值给byte的时候,是不错产生这样的错误的,因为,它们的确是byte的取值范围 ;编译器,是认识常量值的,知道它们的值是 byte 的合法取值范围 ;因此,java允许这样的赋值 ;
byte c = a + b ; // error
为什么,这里又错了呢?因为 a 和 b 都是 变量。编译器虽然可以确定 a 和 b 两个变量的值,都是byte的取值范围,但是由于他们是变量,变量相加的值,编译器在编译器期间是无从得知的,也就是说,到底会不会超过byte的取值范围,编译器是不确定的 ;因此,报错 ;
byte d = 3 + 5 ; // ok
byte e = 125 + 5 ; // error3 + 5 OK 的原因是:编译器是认识常量值的,知道 3 + 5 = 8 ;还没有超过byte的取值范围 ;同样的道理,编译器发现了 125 + 5 = 130 ;超过了byte的取值范围了,因此,报错 ;
byte f = (byte) (127 + 5); // ok
System.out.println(f); // output : -124输出为什么是 -124 ;我们可以把byte的取值范围想象成一个表盘;表盘的正上方是 0 ;表盘的正下方是 - 128 和 127 ;对 byte 进行加减操作的时候,类似于在表盘上移动 ;当127 + 5 的时候,就移动到了 -124 的位置了 ;
byte g = 8 ;
g = g + 10 ; //error
g += 10 ; // ok首先 g = g + 10 ;错误的原因,跟第二条是一样的,由于 g 是个变量,编译器无法得知它和10相加完的具体值 ,是否产生溢出,因此报错;
大家可能都听别人说 g = g + 10 ; 与 g += 10 ; 是等价的 ;;其实 它们不是完全等价的, += 操作符,会默认帮我们进行强转 ;这也解释了 g += 10 ; 是正确的原因 ;底层有个自动强转在里面 ;
涉及基本数据类型的重载
public void aha(char b){}
public void aha(byte b){}
public void aha(short b){}
public void aha(int b){}
public void aha(long b){}
public void aha(float b){}
public void aha(double b){}
当我们想要调用 aha( ) 方法的时候,编译器会根据参数进行选择调用哪一个方法;
但是当没有参数,与我们传入的参数匹配的时候,编译器会将我们传进去的参数进行向上提升 ;
一般都是向上一个类型一个类型的提升,比如byte,先提升到short ,没有合适的,再提升到int 等等,以此类推 ;
其中char,有点特殊;如果没有匹配的话,则直接提升到 int类型 ;
这里需要注意,long 会被 提升为 float ;因为,float 的取值范围是大于 long 的 ; 至于原因,可查看我的另一篇博客: floa取值范围为什么比 long取值范围 大