数据类型

基本类型

类型大小范围默认值包装类
byte1 字节-128 ~ 1270Byte
short2 字节-32768 ~ 327670Short
int4 字节-2³¹ ~ 2³¹-10Integer
long8 字节-2⁶³ ~ 2⁶³-10LLong
float4 字节±3.4×10³⁸0.0fFloat
double8 字节±1.8×10³⁰⁸0.0dDouble
char2 字节0 ~ 65535(Unicode)’�‘Character
boolean取决于 JVMtrue / falsefalseBoolean
// 基本类型初始化
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);               // 任意类型 → String

String

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);  // true

StringBuilder / StringBuffer

StringStringBuilderStringBuffer
可变性不可变可变可变
线程安全安全不安全安全(方法加 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());
}
// 只能用于局部变量,不能用于方法参数、返回值、字段

相关链接