查看下面的代码:
public class ByteTest {
public static void main(String[] args) {
byte a = 1;
byte b = 2;
a = 1+b;
// a+=b;
}
}
发现抱错,编译器提示你提供了一个int类型的数据,但是你需要的是一个byte类型的。
原因是:byte和short类型的数据,在进行计算的时候,会自动提升数据类型为int,所以等号右边的结果类型是int,需要强转为byte类型。
在来看看第7行代码的结果:
编译器正常且结果也正确,是因为“+=”,“++”等等操作符并没有自动类型提升
再来看看下面代码的计算结果:
计算结果出乎我们的意料,为什么byte的127加1变成了-128呢?
我们知道,基本数据类型的取值范围如下:
类型 | 字节长度 | 取值范围 |
int | 4字节 | -2 147 483 648 ~ 2 147 483 647 |
short | 2字节 | -32 768 ~ 32 767 |
long | 8字节 | -9 223 372 036 854 775 808 ~ 9 223 372 036 854 775 807 |
byte | 1字节 | -128 ~ 127 |
float | 4字节 | 大约±3.402 823 47E+38F(6~7位有效数字) |
double | 8字节 | 大约±1.797 693 134 862 315 70E+308(15位有效数字) |
byte的最大值是127,下面是Byte包装类的部分源码:
public final class Byte extends Number implements Comparable<Byte> {
public static final byte MIN_VALUE = -128;
public static final byte MAX_VALUE = 127;
@SuppressWarnings("unchecked")
public static final Class<Byte> TYPE = (Class<Byte>) Class.getPrimitiveClass("byte");
public static String toString(byte b) {
return Integer.toString((int)b, 10);
}
private static class ByteCache {
private ByteCache(){}
static final Byte cache[] = new Byte[-(-128) + 127 + 1];
static {
for(int i = 0; i < cache.length; i++)
cache[i] = new Byte((byte)(i - 128));
}
}
public static Byte valueOf(byte b) {
final int offset = 128;
return ByteCache.cache[(int)b + offset];
}
......
此包装类里面在内里面维护了一个私有的静态内部类,缓存了-128到127直接的byte对应的包装类型,通过value of这个静态方法将结果返回,此时我们取得时候同一个byte值对应的包装对象就全部是一样的。
看下面的代码就知道缓存的作用了:
public class Test {
public static void main(String[] args) {
Integer i1 = 100;
Integer i2 = 100;
Integer i3 = 200;
Integer i4 = 200;
System.out.println(i1 == i2); //true
System.out.println(i3 == i4); //false
}
}
int里面也缓存了从-128到127之间的值,不创建对象,之间使用赋值的方式,100会之间使用缓存里面的值,所以"=="比较的地址值相同,而200超过了缓存范围,会之间使用创建对象的方式进行输出,地址值不相等,所以是false.
下面解释为什么结果是-128:
大家知道,byte类型对应1个字节,也就是8个位,最左边的是符号位,在二进制里面127是01111111,如果还想给127加一的话,结果0111 111变为1000 0000。计算机中存储负数,存的是补码的形式。左边第一位 为符号位。
java中负数的补码转换成十进制如下:
一个数如果为正,则它的原码、反码、补码相同;一个正数的补码,将其转化为十进制,可以直接转换。
已知一个负数的补码,将其转换为十进制数,步骤:
1、先对各位取反;
2、将其转换为十进制数;
3、加上负号,再减去1。
按照上面的步骤:1000 0000的结果为,第一步:0111 1111,第二步:127,第三步:-127-1 = -128,也就是最终的结果了。