数据类型——整数型详解

本文详细介绍了Java中整数型的四种表示形式:十进制、二进制、八进制和十六进制,以及四种基本类型byte、short、int和long的取值范围。强调了整数默认被视为int类型处理,并讨论了自动类型转换和强制类型转换的规则。此外,还探讨了底层转换机制,包括补码表示法及其在存储和运算中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在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

	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值