赖娅闺 发表于 2026-2-2 13:45:03

Java中的数据类型

Java 数据类型详解

目录


[*]数据类型分类
[*]基本数据类型
[*]引用类型
[*]基本类型 vs 引用类型
[*]包装类
[*]String 详解
[*]字符串常量池
[*]内存布局
[*]对象生命周期
[*]常见问题
数据类型分类

Java 数据类型
├── 基本类型(8种)
│   ├── 整数类型:byte, short, int, long
│   ├── 浮点类型:float, double
│   ├── 字符类型:char
│   └── 布尔类型:boolean
└── 引用类型
    ├── 类(如 String)
    ├── 接口
    └── 数组基本数据类型

整数类型

类型位数范围默认值示例byte8位-128 ~ 1270byte b = 100;short16位-32,768 ~ 32,7670short s = 10000;int32位-21亿 ~ 21亿0int i = 100000;long64位极大0Llong l = 100000L;bytea = 127;   // ✅ 最大值
// byte b = 128;// ❌ 超出范围

int   c = 100;
longd = 100000L; // long 需加 L 或 l
longe = 10000000000L; // ✅ 超出int范围必须加L
// longf = 10000000000; // ❌ 编译错误,超出 int 范围浮点类型

类型位数精度默认值示例float32位单精度(7位有效数字)0.0ffloat f = 3.14f;double64位双精度(15位有效数字)0.0double d = 3.14;double a = 3.14;   // 默认是 double
// float b = 3.14;// ❌ 编译错误
floatc = 3.14f;    // ✅字符类型

类型位数说明默认值示例char16位单个 Unicode 字符\u0000char c = 'A';char a = 'A';       // 字符
char b = '中';      // 中文
char c = 65;      // 数字对应字符 'A'
char d = '\u0041';// Unicode 转义,'A'
char e = '\u0000';// null 字符,char 的默认值

// char f = 'AB';// ❌ char 只能存单个字符布尔类型

类型取值默认值示例booleantrue, falsefalseboolean flag = true;boolean a = true;
boolean b = false;引用类型

什么是引用类型

引用类型存储的是对象的地址(引用),对象本身存储在堆中。
常见引用类型

类型说明示例String字符串类String s = "hello";数组数组int[] arr = {1, 2, 3};接口接口类型List list;自定义类用户定义的类Person p = new Person();基本类型 vs 引用类型

对比维度基本类型引用类型(如 String)存储位置栈中,直接存值栈存引用,堆存对象大小固定(如 int 4字节)不固定默认值0/false/\u0000null比较== 比较值== 比较地址,equals() 比较内容内存图示

基本类型:

┌─────────┐
│ int a   │ = 10
└─────────┘
直接存值

引用类型:
栈                  堆
┌─────────┐          ┌─────────┐
│String s │ ────────→│ "hello" │
└─────────┘          └─────────┘
引用变量            实际对象比较示例

// 基本类型
int a = 10;
int b = 10;
System.out.println(a == b);// true(比较值)

// 引用类型
String s1 = new String("hello");
String s2 = new String("hello");
System.out.println(s1 == s2);         // false(不同地址)
System.out.println(s1.equals(s2));    // true(内容相同)包装类

每个基本类型都有对应的包装类:
基本类型包装类说明byteByteshortShortintIntegerlongLongfloatFloatdoubleDoublecharCharacterbooleanBooleanint a = 10;            // 基本类型
Integer b = 10;          // 包装类
Integer c = Integer.valueOf(10); // 显式创建

// 自动装箱/拆箱
Integer d = a;         // 自动装箱
int e = d;               // 自动拆箱String 详解

String 是什么?

String 是类,不是基本类型,是不可变的引用类型。
String 的不可变性

String a = "hello";
String b = a;            // a 和 b 指向同一对象

a = "world";               // a 指向新对象

System.out.println(b);   // 输出: hello(b 不变)
System.out.println(a == b); // false(已不是同一对象)内存变化:

修改前:
a ──→ ["hello"]
      ↑
      b

修改后:
a ──→ ["world"]← 新对象

b ──→ ["hello"]← 原对象不变为什么 String 不可变?

// String 简化版源码
public final class String {
    private final char value[];// final,不能修改

    // 所有修改操作都返回新 String
    public String substring(int beginIndex) {
      return new String(value, beginIndex, count);
    }
}原因说明不可变String 对象一旦创建,内容不能改finalString 类内部用 final 修饰字符数组安全多线程环境下,无需加锁就能安全共享String vs 可变对象

// String - 不可变
String a = "hello";
String b = a;
a = "world";
System.out.println(b);// hello(不变)

// StringBuilder - 可变
StringBuilder sb1 = new StringBuilder("hello");
StringBuilder sb2 = sb1;
sb1.append(" world");
System.out.println(sb2);// hello world(变了!)字符串常量池

什么是字符串常量池

┌─────────────────────────────────────────────────────┐
│                   字符串常量池                     │
│(JVM 堆内存中的一块特殊区域,专门存储字符串字面量)│
│                                                   │
│   "hello"                                           │
│   "world"                                           │
│   "java"                                          │
└─────────────────────────────────────────────────────┘字面量 vs new

方式写法存储位置是否复用隐式(字面量)String s = "hello";字符串常量池✅ 复用显式(new)String s = new String("hello");堆内存(新对象)❌ 新对象动态创建scanner.nextLine()堆内存(新对象)❌ 新对象字面量(隐式赋值)

String a = "hello";
String b = "hello";流程:

[*]JVM 检查常量池中是否有 "hello"
[*]有 → 直接引用(复用)
[*]无 → 在常量池创建 "hello",然后引用
常量池:
┌─────────┐
│ "hello" │ ← a ─┐
└─────────┘       │
                  │ 两者指向同一对象
                  ├─ bSystem.out.println(a == b);// true(同一对象)new(显式赋值)

String c = new String("hello");
String d = new String("hello");流程:

[*]先在常量池检查/创建 "hello"
[*]然后在堆内存强制创建新对象
[*]变量引用堆上的新对象(不是常量池)
常量池:            堆内存:
┌─────────┐      ┌─────────┐
│ "hello" │ ───→   │ "hello" │ ← c
└─────────┘      └─────────┘
                   ┌─────────┐
                   │ "hello" │ ← d
                   └─────────┘System.out.println(c == d);   // false(不同对象)
System.out.println(c == a);   // false(c 在堆,a 在常量池)
System.out.println(c.equals(a)); // true(值相同)scanner 输入

String c = scanner.nextLine(); // 输入: hello
String d = scanner.nextLine(); // 输入: hello
System.out.println(c == d);    // false(每次新对象)内存布局

Java 版本差异

版本常量池位置Java 6 及之前方法区(永久代 PermGen)Java 7+堆Java 8+堆(方法区改为元空间 Metaspace)现代 Java(7+):字符串常量池在堆上。
完整内存布局

String s1 = "first";
String s2 = new String("second");

栈:
┌─────────┐      ┌─────────┐
│   s1    │      │   s2    │
└─────────┘      └─────────┘
↓ 引用            ↓ 引用

堆(都在堆上):
┌───────────────────────────────────────────────────┐
│                                                   │
│常量池区域:         普通堆区域:                  │
│┌─────────┐      ┌─────────────────────┐       │
││ "first" │      │ String对象         │       │
││"second" │      │ value → "second"    │       │
│└─────────┘      └─────────────────────┘       │
│                           ↓                      │
│                     ┌─────────┐                   │
│                     │"second" │ ← 在常量池         │
│                     └─────────┘                   │
│                                                   │
└───────────────────────────────────────────────────┘new String("xxx") 的步骤

1. 先处理 "xxx" 字面量
   → 检查常量池有没有 "xxx"
   → 没有 → 在常量池创建 "xxx"
   → 有 → 复用

2. 再执行 new String()
   → 在普通堆创建新对象
   → 对象内部引用常量池的 "xxx"String s = new String("second");

// 等价于:
String literal = "second";      // 先处理字面量,进常量池
String s = new String(literal); // 再创建堆对象对象生命周期

对象的一生

┌─────────────────────────────────────────────────────────┐
│                   对象一生                               │
├─────────────────────────────────────────────────────────┤
│                                                         │
│1. 创建   →new String() / scanner.nextLine()      │
│   ↓                                                │
│2. 使用   →被变量引用,可以访问                  │
│   ↓                                                │
│3. 失去引用 →变量指向其他对象或离开作用域            │
│   ↓                                                │
│4. 可回收    →等待 GC 清理                        │
│   ↓                                                │
│5. 回收   →GC 自动回收内存                        │
│                                                         │
└─────────────────────────────────────────────────────────┘示例:引用丢失

String s1 = scanner.nextLine();// 创建对象
s1 = scanner.nextLine();         // s1 指向新对象,原对象可被回收垃圾回收(GC)

GC = Garbage Collection,Java 自动内存管理机制。
GC 工作原理:
1. 定期扫描堆内存
2. 找出没有被引用的对象
3. 回收内存不同区域的回收策略

类型生命周期回收方式字面量(常量池)程序运行期间一般不回收动态对象(堆)到无引用时GC 回收基础类型(栈)作用域内自动销毁String a = "hello";// 常量池,程序运行期间存在
String b = scanner.nextLine();// 堆对象
b = null;// 失去引用,等待 GCintern() 方法

将字符串内容放入常量池。
String s = new String("aaa");
s.intern();// 将 "aaa" 内容放入常量池(如果还没)String s1 = new String("aaa");
String s2 = new String("aaa");
String s3 = "aaa";// 字面量,常量池
String s4 = s1.intern();// 返回常量池中的引用

System.out.println(s1 == s2);   // false(堆对象,不同)
System.out.println(s1 == s3);   // false(堆 vs 常量池)
System.out.println(s3 == s4);   // true(都是常量池)常见问题

Q1: \u0000 是什么?

\u0000 是 Unicode 字符的转义表示,表示 Unicode 值为 0 的字符。
方面说明Unicode 值0名称null 字符 / 空字符可见性不可见(控制字符)Java 中char 的默认值char c = '\u0000';          // null 字符
char d = 0;               // 等价写法
System.out.println(c == d); // true
System.out.println((int)c); // 输出: 0Q2: String 引用相同但值不同?

对于 String,不可能。
String a = "hello";
String b = a;
a = "world";
System.out.println(b);// hello(b 不变)核心原因: String 是不可变的,引用相同则值必相同。
Q3: scanner.nextLine() 返回什么?

永远返回 String,无论输入什么。
Scanner scanner = new Scanner(System.in);
String input = scanner.nextLine();// 输入 27 → "27"(字符串)

// 如果要转整数
int num = Integer.parseInt(input);// "27" → 27方法输入 27返回类型nextLine()"27"StringnextInt()27intnextDouble()27.0doubleQ4: 常量池在堆上吗?

是的,现代 Java(7+)中,字符串常量池在堆上。
但常量池是堆中特殊管理的区域,与普通堆对象有区别:
对比维度常量池对象普通堆对象位置堆(特殊区域)堆(普通区域)创建方式字面量、intern()new String()去重✅ 自动去重❌ 不去重生命周期一般长期存在无引用后 GC 回收总结速查表

基本类型速查

类型位数范围默认值byte8-128 ~ 1270short16±3.2万0int32±21亿0long64极大0Lfloat32单精度0.0fdouble64双精度0.0char16单字符\u0000boolean1true/falsefalseString 对比速查

操作结果String a = "hello";
String b = "hello";a == b → trueString c = new String("hello");
String d = new String("hello");c == d → falsea == cfalse(常量池 vs 堆)a.equals(c)true(值相同)记忆口诀

基础类型   引用类型
    ↓            ↓
   栈          栈 + 堆
直接值       引用+对象

字面量       scanner输入
    ↓            ↓
常量池      堆新对象
可复用      不复用

String→ 引用同,值必同(不可变)
StringBuilder → 引用同,值随变(可变)注:同步发布于金蝶开发者社区:Java数据类型

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

樊涵菡 发表于 2026-2-3 09:31:41

这个有用。

纪晴丽 发表于 2026-2-4 04:34:36

鼓励转贴优秀软件安全工具和文档!

洪势 发表于 2026-2-4 08:28:36

yyds。多谢分享

瘴锲如 发表于 2026-2-4 10:52:11

前排留名,哈哈哈

诞楮 发表于 2026-2-6 06:01:16

很好很强大我过来先占个楼 待编辑

捡嫌 发表于 2026-2-7 08:33:55

鼓励转贴优秀软件安全工具和文档!

况雪柳 发表于 2026-2-9 02:36:21

这个有用。

袋岖荤 发表于 2026-2-11 17:42:38

感谢分享,下载保存了,貌似很强大

箝德孜 发表于 2026-2-13 14:09:38

收藏一下   不知道什么时候能用到

庞环 发表于 2026-2-13 16:39:06

懂技术并乐意极积无私分享的人越来越少。珍惜

井晶灵 发表于 2026-2-13 20:25:57

感谢发布原创作品,程序园因你更精彩

洪思思 发表于 2026-2-13 22:02:16

前排留名,哈哈哈

恿榫 发表于 2026-2-16 10:58:51

喜欢鼓捣这些软件,现在用得少,谢谢分享!

稼布欤 发表于 2026-2-26 16:37:33

很好很强大我过来先占个楼 待编辑

郜庄静 发表于 2026-3-1 20:27:08

这个好,看起来很实用

蓝娅萍 发表于 2026-3-1 20:44:01

感谢分享

觐有 发表于 2026-3-11 09:13:23

这个有用。
页: [1]
查看完整版本: Java中的数据类型