Java基础——数据类型(种类、包装类型、缓存机制、装拆箱、精度丢失)

我是一个计算机专业研0的学生卡蒙Camel(刚保研)
记录每天学习过程(主要学习Java、python、人工智能),总结知识点(内容来自:自我总结+网上借鉴)
希望大家能一起发现问题和补充,也欢迎讨论

文章目录

    • Java数据类型
      • 数据类型种类
      • 包装类型和基本类型
      • 包装类型的缓存机制
      • 装箱与拆箱
      • BigDecimal
        • 精度丢失问题
        • 使用BigDecimal解决

Java数据类型

数据类型种类

Java有8大基本数据类型:

类型 关键字 大小 默认值 取值范围
整数类型 byte 1字节 0 -128 到 127
short 2字节 0 -32,768 到 32,767
int 4字节 0 -2^31 到 2^31-1
long 8字节 0L -2^63 到 2^63-1
浮点类型 float 4字节 0.0f 大约±3.40282347E+38F (有效位数6-7位)
double 8字节 0.0d 大约±1.79769313486231570E+308 (有效位数15位)
字符类型 char 2字节 ‘\u0000’ (即0) ‘\u0000’ (0) 到 ‘\uffff’ (65,535)
布尔类型 boolean 不定 false true 或 false

包装类型和基本类型

Java 中的包装类型(Wrapper Class)是用来将基本数据类型(primitive data types)封装成对象的类。每个基本数据类型都有对应的包装类,这些包装类位于 java.lang 包中。

基本数据类型 包装类
boolean Boolean
byte Byte
short Short
int Integer
long Long
float Float
double Double
char Character

两者之间的区别

  • 泛型:包装类型可用于泛型,而基本类型不可以。

  • 存储方式

    • 基本数据类型的局部变量存放在 Java 虚拟机栈中的局部变量表中,基本数据类型的成员变量(未被 static 修饰 )存放在 Java 虚拟机的堆

    • 包装类型属于对象类型,我们知道几乎所有对象实例都存在于堆中。

  • 占用空间:基本数据类型占用空间较小

  • 默认值

    • 基本数据类型不是null

    • 包装类型默认值是null

  • 比较方式

    • 基本数据类型:== 比较的是值

    • 包装类型:== 比较的是对象的内存地址。值比较用equals() 方法。

⚠️注意:基本数据类型的存储位置取决于它们的作用域和声明方式。如果它们是局部变量,那么它们会存放在中;如果它们是成员变量,那么它们会存放在堆/方法区/元空间中。

包装类型的缓存机制

从 Java 5 开始,为了提高性能和节省内存,引入了包装类型的缓存机制。这个机制特别适用于那些频繁使用的数值范围内的值,通过预先创建并存储这些值的对象实例,避免了重复创建相同值的对象。

  • Byte,Short,Integer,Long 这 4 种包装类默认创建了数值 [-128,127] 的相应类型的缓存数据
  • Character 创建了数值在 [0,127] 范围的缓存数据
  • Boolean 直接返回 True or False

因为有缓存机制,所以在缓存好的对象使用 == 判断可能返回的是true,因为他们都常量池中已创建好的对象。

装箱与拆箱

基本数据类型和包装类型的相互转换成为装箱与拆箱。

Integer i = 10; // 装箱
int n = i;	//拆箱

装箱的实质原理就是调用了Integer.valueOf()方法,拆箱就是调用了intvalue()方法。

自动装箱的问题:如果频繁拆装箱的话,也会严重影响系统的性能。我们应该尽量避免不必要的拆装箱操作。

Integer sum = 0;
for(int i = 1;i < 5000;i ++){
    sum += i;
}

上述代码就有先拆箱、再装箱的多余步骤,会影响新能。

BigDecimal

BigDecimal 可以实现对浮点数的运算,不会造成精度丢失。

精度丢失问题

floatdouble 这两种基本数据类型用于存储带有小数部分的数值,但它们并不能精确地表示所有的十进制小数,因为某些十进制小数无法被准确转换为有限长度的二进制小数。例如,0.01 在二进制下是一个无限循环小数.

double a1 = 2.50;
double a2 = 2.49;
System.out.println(a1 - a2); // 输出0.009999999999999787
使用BigDecimal解决
double a = 1.0, b = 0.8;
BigDecimal a2 = new BigDecimal("1.0");
BigDecimal b2 = new BigDecimal("0.8");
System.out.println(a - b); // 0.19999999999999996
System.out.println(a2.subtract(b2)); // 0.2

BigDecimal比较:

BigDecimal a = new BigDecimal("1.0");
BigDecimal b = new BigDecimal("1.00");
BigDecimal c = new BigDecimal("0.8");

BigDecimal x = a.subtract(c);
BigDecimal y = b.subtract(c);

System.out.println(x); /* 0.2 */
System.out.println(y); /* 0.20 */
// 比较内容,不是比较值
System.out.println(Objects.equals(x, y)); /* false */
// 比较值相等用相等compareTo,相等返回0
System.out.println(0 == x.compareTo(y)); /* true */

你可能感兴趣的:(Java基础,java,缓存,python)