DukeDuke
主页
关于我们
主页
关于我们
  • Java

    • Java基础

      • 内存与磁盘
      • 进制转换
      • 数据存储
      • Java基本数据类型
      • HashMap
      • Java四大引用
    • JVM

      • 认识JVM
      • JVM类加载器
      • 运行时数据区
      • 执行引擎
      • 本地方法接口
      • 本地方法库
      • JVM垃圾回收
      • JVM性能监控
      • JVM调优
    • 设计模式
      • 单例模式
      • 工厂模式
      • 策略模式
      • 适配器模式
      • 建造者模式
      • 原型模式
      • 装饰器模式
      • 代理模式
      • 外观模式
      • 享元模式
      • 组合模式
      • 桥接模式
    • Java多线程

      • Java 线程基础详解
      • Java 线程池详解
      • Java ThreadLocal 详解
      • Java volatile 详解
      • Java 线程间通信详解
      • Java 线程安全详解
      • Java 线程调度详解
      • Java 线程优先级详解

      • Java 线程中断详解
      • Java 线程死锁详解
    • Java反射
    • Java 面试题

      • Java 基础概念面试题
      • Java 面向对象编程面试题
      • Java 集合框架面试题
      • Java 多线程与并发面试题
      • JVM 与内存管理面试题
      • Java I/O 与 NIO 面试题
      • Java 异常处理面试题
      • Java 反射与注解面试题
      • Java Spring 框架面试题
      • Java 数据库与 JDBC 面试题
      • Java 性能优化面试题
      • Java 实际项目经验面试题
      • Java 高级特性面试题
      • Java 面试准备建议

Java的基本数据类型

1. 基本数据类型概述

1.1 什么是基本数据类型

**基本数据类型(Primitive Data Types)**是Java语言内置的、不可再分解的数据类型。它们是构建Java程序的基础,直接存储在栈内存中,不是对象。

基本数据类型的特点

  • 内置类型:由Java语言直接提供,无需导入
  • 值类型:直接存储值,不是对象引用
  • 栈存储:存储在栈内存中,访问速度快
  • 不可变:一旦赋值,值本身不可改变(但可以重新赋值)
  • 无方法:不是对象,没有方法可以调用

1.2 Java的8种基本数据类型

Java提供了8种基本数据类型,分为4大类:

类别类型占用字节长度(位)说明
整数类型byte188位有符号整数
short21616位有符号整数
int43232位有符号整数
long86464位有符号整数
浮点类型float43232位单精度浮点数
double86464位双精度浮点数
字符类型char21616位Unicode字符
布尔类型boolean未定义未定义布尔值(通常1字节或4字节)

2. 整数类型

2.1 byte(字节型)

byte是8位有符号整数类型。

基本特性

  • 内存占用:1 字节(8 位)
  • 取值范围:-128 到 127(-2⁷ 到 2⁷-1)
  • 默认值:0
  • 包装类:Byte

取值范围计算

1 字节 = 8 位
有符号整数:使用补码表示
最小值:-128 = -2⁷
最大值:127 = 2⁷ - 1

使用示例

byte b1 = 100;        // 正确
byte b2 = -128;       // 最小值
byte b3 = 127;        // 最大值
// byte b4 = 128;     // 编译错误:超出范围
// byte b5 = -129;    // 编译错误:超出范围

常见用途

  • 文件I/O:读取/写入字节数据
  • 网络通信:传输字节流
  • 图像处理:像素值(0-255)
  • 节省内存:存储小范围整数

2.2 short(短整型)

short是16位有符号整数类型。

基本特性

  • 内存占用:2 字节(16 位)
  • 取值范围:-32,768 到 32,767(-2¹⁵ 到 2¹⁵-1)
  • 默认值:0
  • 包装类:Short

使用示例

short s1 = 1000;           // 正确
short s2 = -32768;         // 最小值
short s3 = 32767;          // 最大值
// short s4 = 32768;       // 编译错误:超出范围

常见用途

  • 节省内存:存储中等范围的整数
  • 数组索引:小数组的索引
  • 较少使用:实际开发中较少使用,通常用int代替

2.3 int(整型)

int是32位有符号整数类型,是Java中最常用的整数类型。

基本特性

  • 内存占用:4 字节(32 位)
  • 取值范围:-2,147,483,648 到 2,147,483,647(-2³¹ 到 2³¹-1)
  • 默认值:0
  • 包装类:Integer

取值范围计算

4 字节 = 32 位
最小值:-2,147,483,648 = -2³¹
最大值:2,147,483,647 = 2³¹ - 1

使用示例

int i1 = 100;                    // 十进制
int i2 = 0xFF;                   // 十六进制:255
int i3 = 0b1010;                 // 二进制:10
int i4 = 2_147_483_647;          // 最大值(可以使用下划线分隔)
int i5 = -2_147_483_648;         // 最小值

常见用途

  • 计数器:循环计数器、数组索引
  • 数学运算:大多数整数计算
  • ID值:用户ID、订单ID等
  • 默认选择:整数类型的默认选择

2.4 long(长整型)

long是64位有符号整数类型。

基本特性

  • 内存占用:8 字节(64 位)
  • 取值范围:-9,223,372,036,854,775,808 到 9,223,372,036,854,775,807(-2⁶³ 到 2⁶³-1)
  • 默认值:0L
  • 包装类:Long

字面量表示

long l1 = 100L;        // 必须加L或l后缀
long l2 = 100l;        // 小写l也可以,但不推荐(容易与1混淆)
long l3 = 9_223_372_036_854_775_807L;  // 最大值

使用示例

long timestamp = System.currentTimeMillis();  // 时间戳
long fileSize = 1024L * 1024 * 1024;          // 文件大小(1GB)
long population = 7_800_000_000L;             // 世界人口

常见用途

  • 时间戳:毫秒级时间戳
  • 大整数:超出int范围的整数
  • 文件大小:文件、内存大小
  • ID生成:分布式ID、雪花算法

3. 浮点类型

3.1 float(单精度浮点型)

float是32位单精度浮点数类型,遵循IEEE 754标准。

基本特性

  • 内存占用:4 字节(32 位)
  • 精度:约7位有效数字
  • 取值范围:约 ±3.4 × 10³⁸
  • 默认值:0.0f
  • 包装类:Float

字面量表示

float f1 = 3.14f;       // 必须加f或F后缀
float f2 = 3.14F;       // 大写F也可以
float f3 = 1.23e2f;     // 科学计数法:123.0
float f4 = 0.1f;        // 注意:浮点数精度问题

精度问题

float f1 = 0.1f;
float f2 = 0.2f;
float sum = f1 + f2;
System.out.println(sum);  // 输出:0.30000001(精度误差)

// 浮点数比较应该使用误差范围
float epsilon = 0.0001f;
if (Math.abs(sum - 0.3f) < epsilon) {
    System.out.println("相等");
}

常见用途

  • 科学计算:对精度要求不高的计算
  • 图形处理:坐标、颜色值
  • 节省内存:大量浮点数时节省内存

3.2 double(双精度浮点型)

double是64位双精度浮点数类型,遵循IEEE 754标准。

基本特性

  • 内存占用:8 字节(64 位)
  • 精度:约15-17位有效数字
  • 取值范围:约 ±1.7 × 10³⁰⁸
  • 默认值:0.0d(或0.0)
  • 包装类:Double

字面量表示

double d1 = 3.14;       // 默认浮点数字面量是double
double d2 = 3.14d;      // 可以加d或D后缀
double d3 = 1.23e10;    // 科学计数法
double d4 = 0.1;        // 仍然有精度问题

精度问题示例

double d1 = 0.1;
double d2 = 0.2;
double sum = d1 + d2;
System.out.println(sum);  // 输出:0.30000000000000004

// 使用BigDecimal进行精确计算
import java.math.BigDecimal;
BigDecimal bd1 = new BigDecimal("0.1");
BigDecimal bd2 = new BigDecimal("0.2");
BigDecimal result = bd1.add(bd2);
System.out.println(result);  // 输出:0.3

常见用途

  • 默认浮点类型:Java中浮点数的默认类型
  • 精确计算:比float精度更高
  • 数学运算:大多数浮点数计算
  • 金融计算:需要更高精度时使用BigDecimal

3.3 浮点数的特殊值

// 正无穷大
double posInf = Double.POSITIVE_INFINITY;
// 或
double posInf2 = 1.0 / 0.0;  // Infinity

// 负无穷大
double negInf = Double.NEGATIVE_INFINITY;
// 或
double negInf2 = -1.0 / 0.0;  // -Infinity

// 非数字(NaN - Not a Number)
double nan = Double.NaN;
// 或
double nan2 = 0.0 / 0.0;  // NaN

// 判断是否为NaN
if (Double.isNaN(nan)) {
    System.out.println("是NaN");
}

// 判断是否为无穷大
if (Double.isInfinite(posInf)) {
    System.out.println("是无穷大");
}

4. 字符类型

4.1 char(字符型)

char是16位无符号整数类型,用于存储Unicode字符。

基本特性

  • 内存占用:2 字节(16 位)
  • 取值范围:0 到 65,535(\u0000 到 \uFFFF)
  • 默认值:'\u0000'(空字符)
  • 包装类:Character

字符表示方式

// 1. 单引号字符字面量
char c1 = 'A';
char c2 = '中';
char c3 = '1';

// 2. Unicode转义序列
char c4 = '\u0041';  // 'A'
char c5 = '\u4e2d';  // '中'

// 3. 转义字符
char c6 = '\n';      // 换行符
char c7 = '\t';      // 制表符
char c8 = '\\';      // 反斜杠
char c9 = '\'';      // 单引号
char c10 = '\"';     // 双引号

// 4. 整数赋值(0-65535)
char c11 = 65;       // 'A'
char c12 = 0x0041;   // 'A'(十六进制)

char的本质

// char实际上是16位无符号整数
char c = 'A';
int code = c;                    // 自动转换为int:65
char c2 = (char) 65;             // 强制转换:'A'

// 字符运算
char c3 = 'A' + 1;               // 'B'
char c4 = (char) ('A' + 1);      // 'B'

常见用途

  • 字符处理:字符串操作、字符判断
  • 字符编码:Unicode字符处理
  • 字符数组:char[]用于字符串底层实现

5. 布尔类型

5.1 boolean(布尔型)

boolean用于存储逻辑值,只有两个值:true和false。

基本特性

  • 内存占用:JVM规范未明确规定,通常为1字节或4字节
  • 取值范围:true 或 false
  • 默认值:false
  • 包装类:Boolean

使用示例

boolean b1 = true;
boolean b2 = false;
boolean b3 = (10 > 5);        // true
boolean b4 = (10 == 5);       // false

// 布尔运算
boolean result1 = true && false;   // false(逻辑与)
boolean result2 = true || false;   // true(逻辑或)
boolean result3 = !true;           // false(逻辑非)

注意事项

// Java中boolean不能与其他类型转换
boolean b = true;
// int i = (int) b;        // 编译错误
// boolean b2 = 1;         // 编译错误(与C/C++不同)

// 必须使用布尔表达式
boolean result = (x > 0);    // 正确
// boolean result2 = x;     // 编译错误(如果x不是boolean)

常见用途

  • 条件判断:if、while、for等控制语句
  • 逻辑运算:布尔逻辑运算
  • 标志位:状态标志、开关标志

6. 基本数据类型总结表

类型大小取值范围默认值包装类说明
byte1字节-128 到 1270Byte8位有符号整数
short2字节-32,768 到 32,7670Short16位有符号整数
int4字节-2³¹ 到 2³¹-10Integer32位有符号整数(最常用)
long8字节-2⁶³ 到 2⁶³-10LLong64位有符号整数
float4字节±3.4×10³⁸0.0fFloat32位单精度浮点数
double8字节±1.7×10³⁰⁸0.0dDouble64位双精度浮点数(默认)
char2字节0 到 65,535'\u0000'Character16位Unicode字符
boolean未定义true/falsefalseBoolean布尔值

7. 包装类(Wrapper Classes)

7.1 什么是包装类

**包装类(Wrapper Classes)**是为8种基本数据类型提供的对象封装类,使基本类型可以像对象一样使用。

包装类对应关系

基本类型包装类说明
byteByte字节包装类
shortShort短整型包装类
intInteger整型包装类
longLong长整型包装类
floatFloat单精度浮点型包装类
doubleDouble双精度浮点型包装类
charCharacter字符型包装类
booleanBoolean布尔型包装类

7.2 包装类的作用

1. 对象操作能力

// 基本类型不是对象,没有方法
int i = 10;
// i.toString();  // 编译错误

// 包装类是对象,有方法
Integer integer = new Integer(10);
String str = integer.toString();  // "10"

2. 支持null值

// 基本类型不能为null
// int i = null;  // 编译错误

// 包装类可以为null
Integer i = null;  // 正确

3. 集合框架支持

// 集合只能存储对象,不能存储基本类型
// List<int> list = new ArrayList<>();  // 编译错误

// 使用包装类
List<Integer> list = new ArrayList<>();
list.add(10);  // 自动装箱

4. 实用方法

// 类型转换
String str = "123";
int i = Integer.parseInt(str);        // 字符串转int
String str2 = Integer.toString(123);  // int转字符串

// 进制转换
String binary = Integer.toBinaryString(10);   // "1010"
String hex = Integer.toHexString(255);         // "ff"

// 比较
int max = Integer.max(10, 20);        // 20
int min = Integer.min(10, 20);        // 10

// 常量
int maxValue = Integer.MAX_VALUE;     // 2,147,483,647
int minValue = Integer.MIN_VALUE;     // -2,147,483,648

7.3 包装类的创建方式

// 方式1:构造函数(已废弃,不推荐)
Integer i1 = new Integer(10);

// 方式2:valueOf方法(推荐)
Integer i2 = Integer.valueOf(10);

// 方式3:自动装箱(Java 5+)
Integer i3 = 10;  // 自动装箱为Integer.valueOf(10)

8. 自动装箱和拆箱

8.1 什么是自动装箱和拆箱

自动装箱(Autoboxing):基本类型自动转换为对应的包装类对象。 自动拆箱(Unboxing):包装类对象自动转换为对应的基本类型。

这是Java 5引入的语法糖,编译器会自动插入转换代码。

8.2 自动装箱示例

// 自动装箱:基本类型 → 包装类
Integer i1 = 10;              // 自动装箱为Integer.valueOf(10)
Integer i2 = Integer.valueOf(10);  // 等价写法

// 方法参数自动装箱
List<Integer> list = new ArrayList<>();
list.add(10);                  // 自动装箱
list.add(20);                  // 自动装箱

8.3 自动拆箱示例

// 自动拆箱:包装类 → 基本类型
Integer i = 10;
int j = i;                     // 自动拆箱为i.intValue()
int k = i.intValue();          // 等价写法

// 运算时自动拆箱
Integer a = 10;
Integer b = 20;
int sum = a + b;               // a和b自动拆箱,然后相加

// 方法参数自动拆箱
int result = Math.max(a, b);    // a和b自动拆箱

8.4 注意事项

1. 性能开销

// 自动装箱会创建对象,有性能开销
Integer sum = 0;
for (int i = 0; i < 1000000; i++) {
    sum += i;  // 每次循环都会自动装箱和拆箱,创建大量对象
}
// 优化:使用基本类型
int sum2 = 0;
for (int i = 0; i < 1000000; i++) {
    sum2 += i;  // 无对象创建,性能更好
}

2. 对象比较

// 包装类比较应该使用equals方法
Integer i1 = 100;
Integer i2 = 100;
System.out.println(i1 == i2);        // true(缓存范围内)

Integer i3 = 200;
Integer i4 = 200;
System.out.println(i3 == i4);        // false(超出缓存范围)

// 正确方式:使用equals
System.out.println(i3.equals(i4));   // true

3. 缓存机制

// Integer缓存-128到127之间的值
Integer a = 127;
Integer b = 127;
System.out.println(a == b);          // true(使用缓存)

Integer c = 128;
Integer d = 128;
System.out.println(c == d);          // false(超出缓存,创建新对象)

// 使用valueOf会利用缓存
Integer e = Integer.valueOf(127);
Integer f = Integer.valueOf(127);
System.out.println(e == f);          // true(使用缓存)

4. null值问题

Integer i = null;
// int j = i;                        // 运行时错误:NullPointerException

// 安全拆箱
int j = (i != null) ? i : 0;         // 正确
int k = (i != null) ? i.intValue() : 0;  // 等价写法

9. 类型转换

9.1 自动类型转换(隐式转换)

自动类型转换:小类型自动转换为大类型,不会丢失精度。

转换规则

byte → short → int → long → float → double
char → int → long → float → double
// 自动转换示例
byte b = 10;
short s = b;        // byte → short
int i = s;          // short → int
long l = i;         // int → long
float f = l;        // long → float
double d = f;       // float → double

char c = 'A';
int i2 = c;         // char → int(Unicode值)

9.2 强制类型转换(显式转换)

强制类型转换:大类型转换为小类型,可能丢失精度或数据。

// 强制转换示例
int i = 100;
byte b = (byte) i;      // int → byte(强制转换)

double d = 3.14;
int i2 = (int) d;       // double → int(丢失小数部分:3)

long l = 300;
byte b2 = (byte) l;     // long → byte(可能溢出)

注意事项

// 1. 整数溢出
int i = 300;
byte b = (byte) i;      // 溢出:300超出byte范围,结果为44

// 2. 精度丢失
double d = 3.14159;
float f = (float) d;    // 精度丢失
int i2 = (int) d;       // 丢失小数部分:3

// 3. 字符转换
char c = 'A';
int i3 = c;             // 自动转换:65
char c2 = (char) 65;    // 强制转换:'A'

9.3 字符串与基本类型转换

字符串转基本类型

// 使用包装类的parseXxx方法
String str = "123";
int i = Integer.parseInt(str);           // 123
long l = Long.parseLong(str);            // 123L
double d = Double.parseDouble("3.14");  // 3.14
float f = Float.parseFloat("3.14f");     // 3.14f
boolean b = Boolean.parseBoolean("true"); // true

// 字符转换
char c = "A".charAt(0);                  // 'A'

基本类型转字符串

// 方式1:String.valueOf()
int i = 123;
String str1 = String.valueOf(i);         // "123"

// 方式2:包装类的toString()
String str2 = Integer.toString(123);     // "123"

// 方式3:字符串拼接(自动转换)
String str3 = "" + 123;                  // "123"

// 方式4:String.format()
String str4 = String.format("%d", 123);  // "123"

10. 实际应用示例

10.1 选择合适的数据类型

// 根据需求选择合适的数据类型

// 1. 文件大小:使用long(可能很大)
long fileSize = 1024L * 1024 * 1024;  // 1GB

// 2. 年龄:使用byte(范围0-150足够)
byte age = 25;

// 3. 计数器:使用int(最常用)
int count = 0;

// 4. 价格:使用BigDecimal(精确计算)
// 或使用long存储分为单位
long priceInCents = 9999;  // 99.99元

// 5. 坐标:使用double(需要精度)
double x = 123.456;
double y = 789.012;

// 6. 标志位:使用boolean
boolean isActive = true;

10.2 类型转换实践

// 用户输入处理
String userInput = "123";
try {
    int number = Integer.parseInt(userInput);
    System.out.println("输入的数字是:" + number);
} catch (NumberFormatException e) {
    System.out.println("输入不是有效数字");
}

// 数值计算
int a = 10;
int b = 3;
double result = (double) a / b;  // 3.333...(避免整数除法)

10.3 性能优化

// 1. 循环中使用基本类型
// 慢:频繁装箱拆箱
Integer sum1 = 0;
for (Integer i = 0; i < 1000000; i++) {
    sum1 += i;
}

// 快:使用基本类型
int sum2 = 0;
for (int i = 0; i < 1000000; i++) {
    sum2 += i;
}

// 2. 集合中使用包装类(必须)
List<Integer> list = new ArrayList<>();
list.add(10);  // 自动装箱,但集合必须使用包装类

11. 总结

11.1 核心要点

  1. Java有8种基本数据类型:byte、short、int、long、float、double、char、boolean
  2. 基本类型直接存储值:存储在栈内存中,访问速度快
  3. 包装类提供对象能力:使基本类型可以像对象一样使用
  4. 自动装箱拆箱:简化基本类型和包装类之间的转换
  5. 类型转换有规则:小类型可自动转大类型,大类型转小类型需强制转换
  6. 选择合适的类型:根据数据范围和精度需求选择合适的数据类型

11.2 关键概念

  • 基本类型 vs 包装类:基本类型存储值,包装类是对象
  • 自动装箱拆箱:语法糖,编译器自动插入转换代码
  • 类型转换:自动转换(小→大)和强制转换(大→小)
  • 精度问题:浮点数有精度误差,精确计算使用BigDecimal
  • 性能考虑:基本类型性能更好,包装类有对象创建开销

11.3 最佳实践

  1. 默认使用int和double:整数用int,浮点数用double
  2. 集合使用包装类:集合框架必须使用包装类
  3. 循环使用基本类型:避免频繁装箱拆箱的性能开销
  4. 浮点数比较:使用误差范围而不是直接比较
  5. 精确计算:金融计算使用BigDecimal而不是double
  6. null值处理:包装类可能为null,拆箱前要检查

理解Java基本数据类型对于:

  • 编写高效代码:选择合适的数据类型
  • 避免类型错误:理解类型转换规则
  • 性能优化:减少不必要的对象创建
  • 问题排查:理解类型相关的bug

至关重要!

最近更新:: 2025/12/29 11:07
Contributors: Duke
Prev
数据存储
Next
HashMap