)
个人主页北极的代码欢迎来访作者简介java后端学习者❄️个人专栏苍穹外卖日记SSM框架深入JavaWeb✨命运的结局尽可永在不屈的挑战却不可须臾或缺前言今天在上课的时候看了一些java基础的八股在这里总结一下希望对大家有一点帮助。摘要本文总结了Java基础数据类型的关键知识点1. 8种基本数据类型及其特性byte(1)、short/char(2)、int/float(4)、long/double(8)包括取值范围和默认值2. 数据类型转换的三种方式自动/强制/字符串及可能出现的精度损失问题3. 包装类的作用与自动装箱拆箱机制解决基本类型无法用于集合、泛型等问题4. 浮点数精度问题及BigDecimal的正确使用方法5. Integer缓存机制-128~127及其对比较的影响。文章通过代码示例详细说明了这些核心概念在实际开发中的应用场景和注意事项。基础知识一、八种基本数据类型Java中的数据类型分为两大类基本数据类型和引用数据类型。其中基本数据类型共有8种是Java程序设计的基石。1.1 数据类型详表数据类型占用大小位数取值范围默认值描述byte1字节8位-128 到 1270最小的整数类型适合节省内存如处理文件或网络流short2字节16位-32768 到 327670较少使用用于需要节省内存且数值范围有限的场景int4字节32位-2^31 到 2^31-10最常用的整数类型满足大多数日常编程需求long8字节64位-2^63 到 2^63-10L表示非常大的整数数值后需加L或lfloat4字节32位1.4E-45 到 3.4028235E380.0f单精度浮点数数值后需加F或fdouble8字节64位4.9E-324 到 1.7976931348623157E3080.0d双精度浮点数Java中浮点数的默认类型char2字节16位\u0000 到 \uffff\u0000表示单个字符采用Unicode编码boolean无明确字节大小不适用true 或 falsefalse用于逻辑判断关键记忆点1字节byte、boolean2字节short、char4字节int、float8字节long、double1.2 默认类型规则java // 整数的默认类型为int int num 100; // ✓ 正确 long bigNum 100L; // 需要加L后缀 // 浮点数的默认类型为double double d 3.14; // ✓ 正确 float f 3.14f; // 需要加f后缀1.3 包装类对应关系除了char对应Character、int对应Integer外其他都是首字母大写byte → Byteshort → Shortint → Integerlong → Longfloat → Floatdouble → Doublechar → Characterboolean → Boolean二、数据类型转换2.1 转换方式Java提供三种数据类型转换方式① 自动类型转换隐式转换java// 小范围 → 大范围自动转换 int intValue 10; long longValue intValue; // 安全自动转换 float floatValue intValue; // 安全自动转换 double doubleValue intValue; // 安全自动转换② 强制类型转换显式转换java// 大范围 → 小范围需要强制转换 long longValue 100L; int intValue (int) longValue; // 可能有数据丢失或溢出 double d 3.14; int i (int) d; // i 3小数部分被舍弃③ 字符串转换javaString str 123; int num Integer.parseInt(str); double d Double.parseDouble(str);2.2 转换可能出现的问题数据溢出javaint largeNum 300; byte b (byte) largeNum; // b 44 // 300的二进制00000001 00101100 // 强制转换为byte只保留低8位00101100 44精度损失javadouble d 3.14; int i (int) d; // i 3损失小数部分三、特殊知识点3.1 char类型的特殊性char是无符号类型不能为负数取值范围从0开始java char c1 65; // 对应字符 A char c2 \u0041; // Unicode表示也是A char c3 A; // 直接字符 // char c4 -1; // ❌ 编译错误char不能为负数3.2 long和int的相互转换java // int → long安全自动转换 int intVal 100; long longVal intVal; // long → int需要强制转换可能溢出 long bigVal 3000000000L; // 超出int范围 int intVal2 (int) bigVal; // 数据丢失结果异常 // 安全的转换方式 if (bigVal Integer.MIN_VALUE bigVal Integer.MAX_VALUE) { int safeVal (int) bigVal; }四、BigDecimal vs double4.1 double的精度问题javaSystem.out.println(0.05 0.01); // 0.060000000000000005 System.out.println(1.0 - 0.42); // 0.5800000000000001 System.out.println(4.015 * 100); // 401.49999999999994 System.out.println(123.3 / 100); // 1.2329999999999999原因double执行的是二进制浮点运算某些十进制小数无法用二进制精确表示就像十进制无法精确表示1/3一样。4.2 使用BigDecimal解决javaimport java.math.BigDecimal; BigDecimal num1 new BigDecimal(0.1); BigDecimal num2 new BigDecimal(0.2); BigDecimal sum num1.add(num2); // 0.3 BigDecimal product num1.multiply(num2); // 0.02 // ⚠️ 注意必须使用字符串构造不要直接使用浮点数 BigDecimal wrong new BigDecimal(0.1); // 仍然有精度问题 BigDecimal correct new BigDecimal(0.1); // ✓ 正确方式结论涉及金钱计算必须使用BigDecimal。重点分析对于初学者来说可能搞不清拆箱和装箱以及包装类这些到底是干嘛的可能仅仅是知道有这个东西不太清晰。一 核心问题基本类型和对象之间不能直接一起玩问题场景Java里有两种东西基本类型int, double, boolean...简单、高效直接存值对象String, List, 自定义类...功能丰富但需要new矛盾出现了很多Java的工具只认对象不认基本类型java// 集合类只能存对象 ArrayListInteger list new ArrayList(); // ✓ 必须用Integer ArrayListint list new ArrayList(); // ❌ 编译错误不能这样写 // 泛型只能用于对象 ListInteger list; // ✓ 正确 Listint list; // ❌ 错误 // 有些方法只接受对象 Thread t new Thread(() - {}); t.wait(1000); // 参数是long但有些API要求对象类型二、装箱和拆箱就是翻译官装箱把基本类型 → 包装成对象拆箱把包装对象 → 还原成基本类型java// 装箱int变成Integer对象 int num 10; Integer obj Integer.valueOf(num); // 手动装箱 Integer obj2 num; // 自动装箱Java 5 // 拆箱Integer对象变回int Integer obj3 new Integer(20); int num2 obj3.intValue(); // 手动拆箱 int num3 obj3; // 自动拆箱Java 5三、为什么需要包装类原因1集合框架只能存对象java// 实际开发中最常见的需求存数字到列表里 ListInteger scores new ArrayList(); scores.add(95); //这里发生了自动装箱int → Integerscores.add(87); scores.add(92); int first scores.get(0); // 自动拆箱Integer → int如果没有包装类你就没法把数字存到ArrayList里这在实际开发中是不可接受的。原因2需要处理空值的情况java// 基本类型的局限性 int score null; // ❌ 编译错误int不能为null // 包装类可以表示缺失 Integer score null; // ✓ 可以表示还没有分数 // 实际应用从数据库查询 public Integer getAgeFromDB(int userId) { // 如果数据库里没有这个用户的年龄返回null if (notExist) return null; // Integer可以返回null return 25; }业务场景用户可能没有填写年龄数据库里是NULL用int无法表示这种空状态。原因3包装类提供了丰富的工具方法java// int本身没有任何方法 int num 123; // num.xxx // 什么都点不出来 // Integer提供了很多实用方法 String str Integer.toString(123); // 123 int parsed Integer.parseInt(456); // 456 String binary Integer.toBinaryString(10); // 1010 int max Integer.max(5, 10); // 10 boolean isDigit Character.isDigit(5); // true四、装箱拆箱的底层原理看看编译器在背后做了什么java// 你写的代码 Integer i 100; int n i; // 编译后实际执行的代码 Integer i Integer.valueOf(100); // 装箱调用valueOf int n i.intValue(); // 拆箱调用intValue五、完整的代码示例对比没有包装类会怎样假设场景java// 假设Java没有包装类你可能需要这样写 class MyInt { int value; MyInt(int v) { value v; } int getValue() { return value; } } ListMyInt list new ArrayList(); list.add(new MyInt(5)); // 每次都要new麻烦且低效 MyInt obj list.get(0); int num obj.getValue(); // 取值也要手动调用方法有了包装类和自动装箱拆箱java// 实际Java代码简洁、高效 ListInteger list new ArrayList(); list.add(5); // 自动装箱 int num list.get(0); // 自动拆箱六、内存和性能角度的理解javaint primitive 10; // 栈内存4字节直接存10 Integer wrapper 10; // 栈内存存引用8字节堆内存存Integer对象16字节 // 总共占用约24字节是int的6倍为什么还要用,因为有些场景必须用包装类集合、泛型、null值这是用空间换功能。七、总结一句话理解概念通俗解释装箱把数字装进盒子里变成对象拆箱从盒子里取出数字为什么需要包装类因为Java的容器集合、泛型不收留基本类型只收留对象实际开发中的平衡日常计算用int、double性能好存集合、表示空值、调用工具方法时用Integer、Double面试高频考点javaInteger a 100; Integer b 100; System.out.println(a b); // true缓存 Integer c 200; Integer d 200; System.out.println(c d); // false超出缓存范围Integer c 200会调用valueOf(200)因为200不在默认缓存范围-128~127内所以会创建两个不同的对象比较的是对象地址因此返回false。Java的Integer类内部实现了⼀个静态缓存池⽤于存储特定范围内的整数值对应的Integer对象。默认情况下这个范围是-128⾄127。当通过Integer.valueOf(int)⽅法创建⼀个在这个范围内的整数对象时并不会每次都⽣成新的对象实例⽽是复⽤缓存中的现有对象会直接从内存中取出不需要新建⼀个对象。为什么Java要设计这个缓存性能优化-128到127是最常用的整数范围频繁创建对象会浪费内存和时间。java// 常见场景循环中使用 for (int i 0; i 1000; i) { list.add(i); // i在0-127之间时复用缓存对象节省内存 }// 永远安全的比较方式 System.out.println(a.equals(b)); // true System.out.println(c.equals(d)); // true结语如果对你有帮助请点赞关注收藏你的支持就是我最大的鼓励