数据类型
基本类型
| 类型 | 大小 | 范围 | 默认值 | 包装类 |
|---|---|---|---|---|
byte | 1 字节 | -128 ~ 127 | 0 | Byte |
short | 2 字节 | -32768 ~ 32767 | 0 | Short |
int | 4 字节 | -2³¹ ~ 2³¹-1 | 0 | Integer |
long | 8 字节 | -2⁶³ ~ 2⁶³-1 | 0L | Long |
float | 4 字节 | ±3.4×10³⁸ | 0.0f | Float |
double | 8 字节 | ±1.8×10³⁰⁸ | 0.0d | Double |
char | 2 字节 | 0 ~ 65535(Unicode) | ’�‘ | Character |
boolean | 取决于 JVM | true / false | false | Boolean |
// 基本类型初始化
byte b = 127;
short s = 32767;
int i = 100;
long l = 100L; // 必须加 L
float f = 3.14f; // 必须加 f
double d = 3.14;
char c = 'A'; // 单引号
char c2 = 65; // 等价 'A'(Unicode 码点)
boolean flag = true;
// 特殊字面量写法
int hex = 0xFF; // 十六进制 255
int bin = 0b1010; // 二进制 10(Java 7+)
long big = 1_000_000L; // 下划线分隔(Java 7+)
// 包装类初始化
Integer n1 = 42; // 自动装箱
Integer n2 = Integer.valueOf(42);
Integer n3 = Integer.parseInt("42"); // String → Integer
// 引用类型默认值为 null
String str = null;
Integer num = null;类型转换
自动转换(隐式,小 → 大)
byte → short → int → long → float → double
char ↗
int i = 100;
long l = i; // 自动转换
double d = i; // 自动转换强制转换(显式,大 → 小,可能精度丢失)
double d = 3.99;
int i = (int) d; // i = 3,截断小数
long l = 300L;
byte b = (byte) l; // 溢出:300 % 256 = 44运算中的类型提升
byte a = 10, b = 20;
// byte c = a + b; // 编译错误!a+b 结果为 int
int c = a + b; // 正确
// 整数运算默认 int,有 long 参与则提升为 long
// 有 float/double 参与则提升为 float/double包装类
装箱与拆箱
Integer i = 42; // 自动装箱:Integer.valueOf(42)
int n = i; // 自动拆箱:i.intValue()
// 拆箱时若包装类为 null 会抛 NullPointerException
Integer x = null;
int y = x; // NullPointerException!整数缓存池
Integer.valueOf() 对 -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(新对象)
System.out.println(c.equals(d)); // true(值比较)常用方法
Integer.parseInt("42"); // String → int
Integer.toString(42); // int → String
Integer.toBinaryString(10); // "1010"
Integer.toHexString(255); // "ff"
Integer.max(a, b);
Integer.compare(a, b);
Integer.MAX_VALUE; // 2147483647
Integer.MIN_VALUE; // -2147483648
String.valueOf(42); // 任意类型 → StringString
String 不可变,底层 char[](Java 8)或 byte[](Java 9+,节省内存)。
String s = "hello";
s.length();
s.charAt(0);
s.substring(1, 3); // "el"
s.indexOf("ll"); // 2
s.contains("ell"); // true
s.startsWith("he");
s.endsWith("lo");
s.toUpperCase();
s.trim(); // 去除首尾空白
s.strip(); // 同 trim,但正确处理 Unicode 空白(Java 11)
s.replace("l", "r");
s.split(",");
s.join("-", "a", "b"); // "a-b"
s.isBlank(); // Java 11,空或全空白返回 true
s.repeat(3); // Java 11字符串比较
"abc".equals("abc"); // true(值比较,推荐)
"abc".equalsIgnoreCase("ABC");
"abc" == "abc"; // true(字符串常量池同一对象)
new String("abc") == "abc"; // false(堆中新对象)字符串常量池
字面量字符串存储在堆的字符串常量池(String Pool)中,相同内容复用同一对象。
String s1 = "hello";
String s2 = "hello";
String s3 = new String("hello");
String s4 = s3.intern(); // 返回常量池中的引用
System.out.println(s1 == s2); // true
System.out.println(s1 == s3); // false
System.out.println(s1 == s4); // trueStringBuilder / StringBuffer
String | StringBuilder | StringBuffer | |
|---|---|---|---|
| 可变性 | 不可变 | 可变 | 可变 |
| 线程安全 | 安全 | 不安全 | 安全(方法加 synchronized) |
| 性能 | 拼接慢 | 快 | 略低于 StringBuilder |
| 适用场景 | 不变字符串 | 单线程拼接 | 多线程拼接 |
底层原理
两者底层都是 char[](Java 9+ 改为 byte[],Latin1 / UTF-16 自适应)。
- 初始容量:
new StringBuilder()→ 16;new StringBuilder(str)→str.length() + 16 - 扩容公式:
新容量 = 旧容量 × 2 + 2,不够则直接使用所需长度
StringBuilder sb = new StringBuilder(); // capacity=16
StringBuilder sb2 = new StringBuilder(64); // capacity=64
StringBuilder sb3 = new StringBuilder("abc"); // capacity=19 (3+16)
sb.capacity(); // 当前缓冲区容量
sb.length(); // 实际字符数
sb.ensureCapacity(100); // 确保至少 100,否则扩容
sb.trimToSize(); // 释放多余缓冲区空间常用 API
StringBuilder sb = new StringBuilder("Hello World");
// 追加
sb.append("!"); // "Hello World!"
sb.append(42); // 追加 int
sb.append(true); // 追加 boolean
sb.append(new char[]{'A','B'}); // 追加 char[]
// 插入
sb.insert(5, ","); // "Hello, World!"
// 删除
sb.delete(0, 3); // 删除 [0,3) 范围
sb.deleteCharAt(0); // 删除指定位置字符
// 替换 / 修改
sb.replace(0, 5, "Hi"); // 替换 [0,5) 为 "Hi"
sb.setCharAt(0, 'h'); // 修改指定位置字符
sb.reverse(); // 反转整个序列
// 查找
sb.indexOf("World"); // 首次出现位置,-1 表示不存在
sb.lastIndexOf("l"); // 最后出现位置
sb.charAt(0); // 指定位置字符
sb.substring(3); // 子串 [3, end)
sb.substring(3, 7); // 子串 [3, 7)
// 输出
String result = sb.toString();StringBuffer 线程安全
StringBuffer 的公开方法均加了 synchronized,多线程下可安全调用;StringBuilder 则无同步,性能更好。
// 多线程下 StringBuffer 安全
StringBuffer buffer = new StringBuffer();
Runnable task = () -> {
for (int i = 0; i < 1000; i++) buffer.append("x");
};
Thread t1 = new Thread(task);
Thread t2 = new Thread(task);
t1.start(); t2.start();
t1.join(); t2.join();
System.out.println(buffer.length()); // 始终 2000实际开发中极少需要 StringBuffer;多线程拼接优先考虑 Collectors.joining() 或局部变量 StringBuilder(不共享)。
最佳实践
// 循环拼接必须用 StringBuilder
StringBuilder sb = new StringBuilder();
for (String s : list) {
sb.append(s).append(",");
}
// 非循环的 + 拼接,编译器自动优化为 StringBuilder,无需手动改写
String s = "a" + "b" + "c";
// 预估容量,避免多次扩容
StringBuilder sb2 = new StringBuilder(list.size() * 16);
// Java 8+ 推荐用 StringJoiner 做带分隔符拼接
StringJoiner sj = new StringJoiner(", ", "[", "]");
sj.add("a"); sj.add("b"); sj.add("c");
System.out.println(sj); // [a, b, c]
// Stream + Collectors
String joined = list.stream().collect(Collectors.joining(", ", "[", "]"));数组
int[] arr = new int[5]; // 默认值 0
int[] arr2 = {1, 2, 3};
int[][] matrix = new int[3][4];
int[][] jagged = {{1,2}, {3,4,5}}; // 锯齿数组
arr.length;
Arrays.sort(arr);
Arrays.binarySearch(arr, 3);
Arrays.fill(arr, 0);
Arrays.copyOf(arr, 10); // 扩容到 10
Arrays.copyOfRange(arr, 1, 3);
Arrays.equals(arr, arr2);
Arrays.toString(arr); // "[1, 2, 3]"var(局部变量类型推断,Java 10+)
var list = new ArrayList<String>(); // 推断为 ArrayList<String>
var map = Map.of("a", 1, "b", 2);
for (var entry : map.entrySet()) {
System.out.println(entry.getKey());
}
// 只能用于局部变量,不能用于方法参数、返回值、字段