在java语言中整数型字面量有4种表示形式:
- 十进制(最常用的)
- 二进制
- 八进制
- 十六进制
public class IntTest01{
public static void main(String[] args){
int a = 10;// 十进制
System.out.println(a); // 10
int b = 010;// 八进制
System.out.println(b); // 8
int c = 0x10;// 十六进制
System.out.println(c); // 16
int x = 16; //十进制方式
System.out.println(x);//16
int d = 0b10;// 二进制(JDK8及以上版本支持)
System.out.println(d); // 2
}
}
整数型在java语言中共4种类型:
- byte 1个字节 -28 ~ 28-1 (-128~127)
- short 2个字节 -216 ~ 216-1 (-32768~32767)
- int 4个字节 -232 ~ 232-1(-2147483648~2147483647)
- long 8个字节 -264~264-1
在计算机中,1个字节 = 8个二进制位 即1byte = 8bit
对于以上的四个类型来说,最常用的是int。(开发的时候不用斤斤计较,直接选择使用int就行了。)
public class IntTest02{
public static void main(String[] args){
int a = 100;//整数型的“字面量/数据”默认被当做int类型处理
System.out.println(a);
long b = 200;// 200这个字面量默认被当做int类型来处理,b变量是long类型,此时发生类型转换
// int类型占4个字节,long类型占8个字节小容量可以自动转换成大容量,这种操作被称为:自动类型转换。
System.out.println(b);
long c = 300L;// 在整数型字面量300后面添加一个L之后,300L联合起来就是一个long类型的字面量,不存在类型转换
System.out.println(c);
long d = 2147483647; // 默认被当做int来处理,2147483647是int最大值
// d变量是long类型,小容量可以自动赋值给大容量,自动类型转换
System.out.println(d);
// 错误: 整数太大
long e = 2147483648;// 在java中,整数型字面量一上来编译器就会将它看做int类型
// 而2147483648已经超出了int的范围,所以在没有赋值之前就出错了
// 并不是e放不下2147483648,e是long类型,完全可以容纳2147483648
// 只不过2147483648本身已经超出了int范围,所以编译器报错
// 怎么解决这个问题呢?
long e = 2147483648L;
System.out.println(e);
}
}
一条非常重要的结论,必须记住:
- 在任何情况下,整数型的“字面量/数据”默认被当做int类型处理。
- 如果希望该“整数型字面量”被当做long类型来处理,需要在“字面量”后面添加L/l (建议使用大写L,因为小写l和1傻傻分不清。)
自动类型转换和强制转换
- 小容量可以直接赋值给大容量,称为自动类型转换。
- 大容量不能直接赋值给小容量,需要使用强制类型转换符进行强转。
但需要注意的是:加强制类型转换符之后,虽然编译通过了,但是运行
的时候可能会损失精度。
底层是怎么进行强制类型转换的呢?
- long类型100L:00000000 00000000 00000000 00000000 00000000 00000000 00000000 01100100
- 以上的long类型100L强转为int类型,会自动将“前面”的4个字节砍掉:00000000 00000000 00000000 01100100
public class IntTest03{
public static void main(String[] args){
long x = 100L;// 100L是long类型字面量,x是long类型字面量。不存在类型转换
int y = x;// 编译错误信息:错误: 不兼容的类型: 从long转换到int可能会有损失
// x是long类型,占用8个字节,而y变量是int类型,占用4个字节,大容量不可以直接赋值给小容量
int y = (int)x; // 这个(int)就是强制类型转换符,加上去就能编译通过。
// 但是编译虽然过了,但是运行时可能损失精度(当字面值大于范围时)
System.out.println(y); // 100
int a = 100;// 定义变量a int类型,赋值100
System.out.println(a);
int b = a; // 将变量a中保存的值100复制一份给b变量。
System.out.println(b);
}
}
java中有一个语法规则:
当这个整数型字面量没有超出byte的取值范围,那么这个整数型字面量可以直接赋值给byte类型的变量。(这种语法机制是为了方便写代码,而存在的。)
public class IntTest04{
public static void main(String[] args){
// 分析:以下代码编译可以通过吗?不可以,错误: 不兼容的类型: 从int转换到byte可能会有损失
// 300 被默认当做int类型,b变量是byte类型
// 大容量转换成小容量,要想编译通过,必须使用强制类型转换符
byte b = 300;
// 要想让以上的程序编译通过,必须加强制类型转换符
// 虽然编译通过了,但是可能精度损失。
// 300这个int类型对应的二进制:00000000 00000000 00000001 00101100
// byte占用1个字节,砍掉前3个字节,结果是:00101100 (44)
byte b = (byte)300;
System.out.println(b); // 44
// 这个编译能通过吗?
// 1是int类型,默认被当做int类型来看。
// x是byte类型,1个字节,大容量无法直接转换成小容量。
// 按说是编译报错的但是却没有报错
byte x = 1;
byte y = 127;
byte z = 128;// 错误: 不兼容的类型: 从int转换到byte可能会有损失
// 当整数型字面量没有超出short类型取值范围的时候,该字面量可以直接赋值给short
// 类型的变量。
short s = 1;
short s1 = 32767;
short s2 = 32768;// 错误: 不兼容的类型: 从int转换到short可能会有损失
System.out.println(s);
System.out.println(s1);
}
}
原码 反码 补码
-
计算机在任何情况下都只能识别二进制,二进制有:原码 反码 补码
-
计算机在底层存储数据的时候,一律存储的是“二进制的补码形式”
计算机采用补码形式存储数据的原因是:补码形式效率最高。 -
记住:
- 对于一个正数来说:二进制原码、反码、补码是同一个,完全相同。
int i = 1;
对应的二进制原码:00000000 00000000 00000000 00000001
对应的二进制反码:00000000 00000000 00000000 00000001
对应的二进制补码:00000000 00000000 00000000 00000001 - 对于一个负数来说:二进制原码、反码(原码的符号位不变,其它位取反)、补码(反码+1)
byte i = -1;
对应的二进制原码:10000001
对应的二进制反码:11111110
对应的二进制补码:11111111
- 对于一个正数来说:二进制原码、反码、补码是同一个,完全相同。
-
分析 byte b = (byte)150;
这个b是多少?
int类型的4个字节的150的二进制码是什么?
00000000 00000000 00000000 10010110
将以上的int类型强制类型转为1个字节的byte,最终在计算机中的二进制码是:10010110千万要注意:计算机永远存储的都是二进制补码形式。也就是说上面 10010110 这个是一个二进制补码形式,你可以采用逆推导的方式推算出 这个二进制补码对应的原码是啥!!!!!! 10010110 ---> 二进制补码形式 10010101 ---> 二进制反码形式 11101010 ---> 二进制原码形式
public class IntTest05{
public static void main(String[] args){
// 编译报错:因为150已经超出了byte取值范围,不能直接赋值,需要强转
//byte b = 150;
byte b = (byte)150;
// 这个结果会输出多少呢?
System.out.println(b); // -106
}
}
byte、char、short做混合运算的时候,各自先转换成int再做运算
public class IntTest06{
public static void main(String[] args){
char c1 = 'a';
byte b = 1;
// 这里的"+"是负责求和的
System.out.println(c1 + b); // 98
// 错误: 不兼容的类型: 从int转换到short可能会有损失
short s = c1 + b; // 编译器不知道这个加法最后的结果是多少。只知道是int类型
// 这样修改行吗?
//错误: 不兼容的类型: 从int转换到short可能会有损失
short s = (short)c1 + b;
short s = (short)(c1 + b);
int a = 1;
//错误: 不兼容的类型: 从int转换到short可能会有损失
// short x = 1; 可以
short x = a; // 不可以,编译器只知道a是int类型,不知道a中存储的是哪个值。
System.out.println(x);
}
}
多种数据类型做混合运算的时候,最终的结果类型是“最大容量”对应的类型。
char+short+byte 除外
因为char + short + byte混合运算的时候,会各自先转换成int再做运算。
public class IntTest07{
public static void main(String[] args){
long a = 10L;
char c = 'a';
short s = 100;
int i = 30;
// 求和
System.out.println(a + c + s + i); //237
// 错误: 不兼容的类型: 从long转换到int可能会有损失
// 计算结果是long类型
int x = a + c + s + i;
int x = (int)(a + c + s + i);
System.out.println(x);
// 以下程序执行结果是?
// java中规定,int类型和int类型最终的结果还是int类型。
int temp = 10 / 3; // / 是除号。(最终取整)
System.out.println(temp); // 3.33333吗?结果是:3
// 在java中计算结果不一定是精确的。
int temp2 = 1 / 2;
System.out.println(temp2); // 0
}
}