1. 底层实现
特性 | C语言 | Java |
---|---|---|
本质 | 字符数组 | 对象(java.lang.String 类) |
结尾符 | \0 |
无(内部封装长度字段) |
内存管理 | 手动分配/释放 | 自动垃圾回收(GC) |
C语言:
<C>
char str[] = "Hello"; // 栈区数组 char *str_ptr = malloc(6); // 堆区指针 strcpy(str_ptr, "Hello"); free(str_ptr); // 必须手动释放
Java:
<JAVA>
String s1 = "Hello"; // 字面量(在字符串常量池) String s2 = new String("Hello"); // 堆对象
2. 可变性
语言 | 可变性 | 示例 |
---|---|---|
C | 可变 | 直接修改字符数组元素(可能覆盖\0 导致错误) |
Java | 不可变 | 每次修改生成新对象(安全但可能影响性能) |
C示例:
<C>
char str[10] = "Hello";
str[0] = 'h'; // 直接修改 → "hello",原地址不变
Java示例:
<JAVA>
String s = "Hello";
s = s.concat(" World"); // 生成新对象,原对象未变
3. 操作安全性
语言 | 常见风险 | Java安全机制 |
---|---|---|
C | 缓冲区溢出、内存泄漏、越界访问 | 无(依赖开发者手动控制) |
Java | 无越界访问 | 索引检查、自动垃圾回收 |
C风险示例:
<C>
char str[5]; strcpy(str, "HelloWorld"); // 缓冲区溢出 ⇒ 程序崩溃或安全漏洞
Java保护:
<JAVA>
String s = "Hello"; char c = s.charAt(10); // 抛出StringIndexOutOfBoundsException
4. 操作函数对比
操作 | C语言(需头文件 <string.h> ) |
Java(String类方法) |
---|---|---|
长度获取 | strlen(str) |
str.length() |
复制 | strcpy(dest, src) (需手动分配内存) |
newStr = str1 + str2 或 concat() |
拼接 | strcat(dest, src) (可能溢出) |
StringBuilder /StringBuffer |
比较 | strcmp(str1, str2) |
equals() 、compareTo() |
C语言示例:
<C>
char src[] = "World";
char dest[20] = "Hello";
strcat(dest, src); // dest变为"HelloWorld"
Java示例:
<JAVA>
String s1 = "Hello";
String s2 = "World";
String s3 = s1 + s2; // 自动创建新对象
5. 性能与适用场景
场景 | C语言 | Java |
---|---|---|
高性能系统编程 | ✅ 直接内存操作、无开销 | ❌ 间接内存访问、GC开销 |
应用层开发 | ❌ 不安全、开发效率低 | ✅ 安全性高、开发便捷 |
总结
- C字符串:
- 手动内存管理,灵活但风险高。
- 适合嵌入式系统、操作系统等底层开发。
- Java String:
- 对象封装,自动内存管理,安全但可能产生性能损耗。
- 适合Web应用、企业级系统等安全性要求高的场景。