Java的基本数据类型

1.基本数据类型

Java的基本数据类型有四类八种,分别是整型、浮点型、字符型、布尔型四类,byte、short、int、long、float、double、char、boolean八种。

1.1 整型

类型存储需求取值范围默认值
byte1字节-128 ~ 1270
short2字节-32768 ~ 327670
int4字节- 231 ~ 231-1 (刚刚超过20亿)0
long8字节- 263 ~ 263-10L

1.2 浮点型

类型存储需求取值范围默认值
float4字节约 ±3.40282347E+38F(有效位数为6~7位)0.0f
double8字节约 ±1.79769313486231570E+308(有效位数为15位)0.0d

通常情况下,float类型的精度并不能满足需求,因而浮点型字面量的默认类型为double。

1.3 字符型

char类型需要使用2字节存储空间,使用字面量赋值时需要使用单引号括起来(双引号表示字符串),默认值为 ‘u0000’。
char类型原本用于表示单个字符,但随着世界发展,有些字符需要使用两个char值才能存储,char类型逐渐不能满足需要,因而除非必要,否则不建议使用char类型。

1.4 布尔型

boolean类型只有 true 和 false 两个值,用于进行逻辑判断,默认值为 false,占用空间并没有确切给出,具体可参考以下文章 。
java中boolean类型基础数据在内存中占用的空间大小分析

2. 数据类型转换

2.1 数据类型转换

在这里插入图片描述
上图表示Java中的合法类型转换,其中6个实线箭头表示转换时无精度丢失,虚线箭头表示可能发生精度丢失。
当一个整型操作数和一个浮点型操作数用二元操作符连接时,会先将操作数转为同一类型进行计算。

  • 当两个操作数有一个是 double 类型时,另一个操作数会转为 double 类型;
  • 否则,如果有一个操作数是 float 类型,另一个操作数会转为 float 类型;
  • 否则,如果有一个操作数是 long 类型,另一个操作数会转为 long 类型;
  • 否则,两个操作数都会被转为 int 类型。

除此之外,还可以使用强制类型转换进行类型转换,其语法格式是在圆括号中写入希望转换的目标类型,然后紧跟待转换的变量,如

double x = 9.96;
int cx = (int) x;

2.2 long 自动转为 float

思考一个问题,long 类型占用8字节,float 类型占用4字节,为什么 float 类型可表示的范围比 long 类型要大,同时 long 类型转为 float 类型会发生精度丢失?

要回答这个问题,我们需要了解整型和浮点型在内存中的存储结构,long 类型是有符号的二进制补码表示的整数,而 float 采用 IEEE754 标准进行表示,其结构为:

  • 第一位是符号位
  • 接下来的8位是指数域
  • 剩下23位是小数域,取值范围是 [1,2) 或 [0,1)

符号位用 S 表示,指数域用 E 表示,小数域用 M 表示,则计算方法为 (-1)S × M × 2E ,其中指数域 E ,最大为255,因此 float 表示范围比 long 要大。
同时,二进制和小数并不是一一对应的,如 0.3,因而 long 类型转为 float 类型可能会丢失精度。

3. 包装类

3.1 基本类型和包装类出现的原因

Java中一切皆对象。但基本类型比较特殊,它们特别小、简单,若是将其使用 new 存储在堆中,往往不是特别有效,因此,对于这些类型,Java不使用 new 创建变量,而是创建一个并非是引用的“自动”变量,将这个变量的值直接存储在堆栈中,这样会更加高效。
但这使得基本类型并不具备对象的性质,为了和其他对象“接轨”于是出现了包装类。举个例子,在使用集合类型时,其中必须存储对象而不能是基本类型。

3.2 自动装箱和自动拆箱

自动装箱和自动拆箱是Java1.5才有的功能。
简单来说,自动装箱就是自动将基本数据类型转换为包装器类型;自动拆箱就是自动将包装器类型转换为基本数据类型。
通过反编译可以得知,自动装箱是调用对应包装类的 valueOf 方法,而自动拆箱是调用包装类的 xxxValue 方法。

public class Main {
    public static void main(String[] args) {
	    //自动装箱,这里会自动执行 Integer.valueOf(int) 方法
	    Integer ir1 = 100;
	    Integer ir2 = 100;
	    Integer ir3 = 200;
	    Integer ir4 = 200;
	    //自定拆箱,这里会自动执行 ir1 .intValue 方法
	    int i = ir1;
    }
}

这里有个点需要注意,通过查看源码我们可以得知,Byte、Short、Integer、Long 这四个类型将 [-128, 127] 区间的整数都放在了cache中,因此上述例子中变量 ir1 和 ir2 实际指向同一个地址,而ir3和 ir4则指向不同的地址。除此之外,还可以看到 Character 类型同样缓存了数据,而 Float 和 Double 没有。

3.3 自动装箱和自动拆箱发生的时机

  • 赋值和传参的时候,需要包装类就装箱,需要基本类型就拆箱
  • 当包装类与基本类型用算数操作符(±*/%)连接时,会进行拆箱操作
  • 当包装类与基本类型用 == 操作符连接时,会进行拆箱操作
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值