找回密码
 立即注册
首页 业界区 安全 Java中的数据类型

Java中的数据类型

赖娅闺 1 小时前
Java 数据类型详解

目录


  • 数据类型分类
  • 基本数据类型
  • 引用类型
  • 基本类型 vs 引用类型
  • 包装类
  • String 详解
  • 字符串常量池
  • 内存布局
  • 对象生命周期
  • 常见问题
数据类型分类
  1. Java 数据类型
  2. ├── 基本类型(8种)
  3. │   ├── 整数类型:byte, short, int, long
  4. │   ├── 浮点类型:float, double
  5. │   ├── 字符类型:char
  6. │   └── 布尔类型:boolean
  7. └── 引用类型
  8.     ├── 类(如 String)
  9.     ├── 接口
  10.     └── 数组
复制代码
基本数据类型

整数类型

类型位数范围默认值示例byte8位-128 ~ 1270byte b = 100;short16位-32,768 ~ 32,7670short s = 10000;int32位-21亿 ~ 21亿0int i = 100000;long64位极大0Llong l = 100000L;
  1. byte  a = 127;     // ✅ 最大值
  2. // byte b = 128;  // ❌ 超出范围
  3. int   c = 100;
  4. long  d = 100000L; // long 需加 L 或 l
  5. long  e = 10000000000L; // ✅ 超出int范围必须加L
  6. // long  f = 10000000000; // ❌ 编译错误,超出 int 范围
复制代码
浮点类型

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

类型位数说明默认值示例char16位单个 Unicode 字符\u0000char c = 'A';
  1. char a = 'A';       // 字符
  2. char b = '中';      // 中文
  3. char c = 65;        // 数字对应字符 'A'
  4. char d = '\u0041';  // Unicode 转义,'A'
  5. char e = '\u0000';  // null 字符,char 的默认值
  6. // char f = 'AB';  // ❌ char 只能存单个字符
复制代码
布尔类型

类型取值默认值示例booleantrue, falsefalseboolean flag = true;
  1. boolean a = true;
  2. 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() 比较内容内存图示
  1. 基本类型:
  2. ┌─────────┐
  3. │ int a   │ = 10
  4. └─────────┘
  5.   直接存值
  6. 引用类型:
  7. 栈                    堆
  8. ┌─────────┐          ┌─────────┐
  9. │String s │ ────────→│ "hello" │
  10. └─────────┘          └─────────┘
  11. 引用变量            实际对象
复制代码
比较示例
  1. // 基本类型
  2. int a = 10;
  3. int b = 10;
  4. System.out.println(a == b);  // true(比较值)
  5. // 引用类型
  6. String s1 = new String("hello");
  7. String s2 = new String("hello");
  8. System.out.println(s1 == s2);         // false(不同地址)
  9. System.out.println(s1.equals(s2));    // true(内容相同)
复制代码
包装类

每个基本类型都有对应的包装类:
基本类型包装类说明byteByteshortShortintIntegerlongLongfloatFloatdoubleDoublecharCharacterbooleanBoolean
  1. int a = 10;              // 基本类型
  2. Integer b = 10;          // 包装类
  3. Integer c = Integer.valueOf(10); // 显式创建
  4. // 自动装箱/拆箱
  5. Integer d = a;           // 自动装箱
  6. int e = d;               // 自动拆箱
复制代码
String 详解

String 是什么?

String 是类,不是基本类型,是不可变的引用类型。
String 的不可变性
  1. String a = "hello";
  2. String b = a;              // a 和 b 指向同一对象
  3. a = "world";               // a 指向新对象
  4. System.out.println(b);     // 输出: hello(b 不变)
  5. System.out.println(a == b); // false(已不是同一对象)
复制代码
  1. 内存变化:
  2. 修改前:
  3. a ──→ ["hello"]
  4.       ↑
  5.       b
  6. 修改后:
  7. a ──→ ["world"]  ← 新对象
  8. b ──→ ["hello"]  ← 原对象不变
复制代码
为什么 String 不可变?
  1. // String 简化版源码
  2. public final class String {
  3.     private final char value[];  // final,不能修改
  4.     // 所有修改操作都返回新 String
  5.     public String substring(int beginIndex) {
  6.         return new String(value, beginIndex, count);
  7.     }
  8. }
复制代码
原因说明不可变String 对象一旦创建,内容不能改finalString 类内部用 final 修饰字符数组安全多线程环境下,无需加锁就能安全共享String vs 可变对象
  1. // String - 不可变
  2. String a = "hello";
  3. String b = a;
  4. a = "world";
  5. System.out.println(b);  // hello(不变)
  6. // StringBuilder - 可变
  7. StringBuilder sb1 = new StringBuilder("hello");
  8. StringBuilder sb2 = sb1;
  9. sb1.append(" world");
  10. System.out.println(sb2);  // hello world(变了!)
复制代码
字符串常量池

什么是字符串常量池
  1. ┌─────────────────────────────────────────────────────┐
  2. │                   字符串常量池                       │
  3. │  (JVM 堆内存中的一块特殊区域,专门存储字符串字面量)  │
  4. │                                                     │
  5. │   "hello"                                           │
  6. │   "world"                                           │
  7. │   "java"                                            │
  8. └─────────────────────────────────────────────────────┘
复制代码
字面量 vs new

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

  • JVM 检查常量池中是否有 "hello"
  • 有 → 直接引用(复用)
  • 无 → 在常量池创建 "hello",然后引用
  1. 常量池:
  2. ┌─────────┐
  3. │ "hello" │ ← a ─┐
  4. └─────────┘       │
  5.                   │ 两者指向同一对象
  6.                   ├─ b
复制代码
  1. System.out.println(a == b);  // true(同一对象)
复制代码
new(显式赋值)
  1. String c = new String("hello");
  2. String d = new String("hello");
复制代码
流程:

  • 先在常量池检查/创建 "hello"
  • 然后在堆内存强制创建新对象
  • 变量引用堆上的新对象(不是常量池)
  1. 常量池:            堆内存:
  2. ┌─────────┐        ┌─────────┐
  3. │ "hello" │ ───→   │ "hello" │ ← c
  4. └─────────┘        └─────────┘
  5.                    ┌─────────┐
  6.                    │ "hello" │ ← d
  7.                    └─────────┘
复制代码
  1. System.out.println(c == d);   // false(不同对象)
  2. System.out.println(c == a);   // false(c 在堆,a 在常量池)
  3. System.out.println(c.equals(a)); // true(值相同)
复制代码
scanner 输入
  1. String c = scanner.nextLine(); // 输入: hello
  2. String d = scanner.nextLine(); // 输入: hello
  3. System.out.println(c == d);    // false(每次新对象)
复制代码
内存布局

Java 版本差异

版本常量池位置Java 6 及之前方法区(永久代 PermGen)Java 7+Java 8+(方法区改为元空间 Metaspace)现代 Java(7+):字符串常量池在堆上。
完整内存布局
  1. String s1 = "first";
  2. String s2 = new String("second");
  3. 栈:
  4. ┌─────────┐      ┌─────────┐
  5. │   s1    │      │   s2    │
  6. └─────────┘      └─────────┘
  7.   ↓ 引用            ↓ 引用
  8. 堆(都在堆上):
  9. ┌───────────────────────────────────────────────────┐
  10. │                                                   │
  11. │  常量池区域:         普通堆区域:                  │
  12. │  ┌─────────┐        ┌─────────────────────┐       │
  13. │  │ "first" │        │ String对象           │       │
  14. │  │"second" │        │ value → "second"    │       │
  15. │  └─────────┘        └─────────────────────┘       │
  16. │                             ↓                      │
  17. │                     ┌─────────┐                   │
  18. │                     │"second" │ ← 在常量池         │
  19. │                     └─────────┘                   │
  20. │                                                   │
  21. └───────────────────────────────────────────────────┘
复制代码
new String("xxx") 的步骤
  1. 1. 先处理 "xxx" 字面量
  2.    → 检查常量池有没有 "xxx"
  3.    → 没有 → 在常量池创建 "xxx"
  4.    → 有 → 复用
  5. 2. 再执行 new String()
  6.    → 在普通堆创建新对象
  7.    → 对象内部引用常量池的 "xxx"
复制代码
  1. String s = new String("second");
  2. // 等价于:
  3. String literal = "second";      // 先处理字面量,进常量池
  4. String s = new String(literal); // 再创建堆对象
复制代码
对象生命周期

对象的一生
  1. ┌─────────────────────────────────────────────────────────┐
  2. │                   对象一生                               │
  3. ├─────────────────────────────────────────────────────────┤
  4. │                                                         │
  5. │  1. 创建     →  new String() / scanner.nextLine()      │
  6. │     ↓                                                  │
  7. │  2. 使用     →  被变量引用,可以访问                    │
  8. │     ↓                                                  │
  9. │  3. 失去引用 →  变量指向其他对象或离开作用域            │
  10. │     ↓                                                  │
  11. │  4. 可回收    →  等待 GC 清理                          │
  12. │     ↓                                                  │
  13. │  5. 回收     →  GC 自动回收内存                        │
  14. │                                                         │
  15. └─────────────────────────────────────────────────────────┘
复制代码
示例:引用丢失
  1. String s1 = scanner.nextLine();  // 创建对象
  2. s1 = scanner.nextLine();         // s1 指向新对象,原对象可被回收
复制代码
垃圾回收(GC)

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

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

将字符串内容放入常量池。
  1. String s = new String("aaa");
  2. s.intern();  // 将 "aaa" 内容放入常量池(如果还没)
复制代码
  1. String s1 = new String("aaa");
  2. String s2 = new String("aaa");
  3. String s3 = "aaa";  // 字面量,常量池
  4. String s4 = s1.intern();  // 返回常量池中的引用
  5. System.out.println(s1 == s2);   // false(堆对象,不同)
  6. System.out.println(s1 == s3);   // false(堆 vs 常量池)
  7. System.out.println(s3 == s4);   // true(都是常量池)
复制代码
常见问题

Q1: \u0000 是什么?

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

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

永远返回 String,无论输入什么。
  1. Scanner scanner = new Scanner(System.in);
  2. String input = scanner.nextLine();  // 输入 27 → "27"(字符串)
  3. // 如果要转整数
  4. 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(值相同)记忆口诀
  1. 基础类型     引用类型
  2.     ↓            ↓
  3.    栈          栈 + 堆
  4. 直接值       引用+对象
  5. 字面量       scanner输入
  6.     ↓            ↓
  7. 常量池        堆新对象
  8. 可复用        不复用
  9. String  → 引用同,值必同(不可变)
  10. StringBuilder → 引用同,值随变(可变)
复制代码
注:同步发布于金蝶开发者社区:Java数据类型

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

相关推荐

您需要登录后才可以回帖 登录 | 立即注册