1. C 和 Java 中字符串和字符数组的对比
实现原理
在 C 语言中,字符串和字符数组本质上都是一块连续的内存空间,需要转义0(\0)结束符;
在 Java 中,字符串和字符数组有本质区别,字符串是 String 对象,而字符数组是数组对象,均不需要结束符。如果是数组对象,对象内存区域中有一个字段表示数组的长度,而 String 相当于字符数组的包装类。
java.lang.String
public final class String {
private final char value[];
private int hash;
...
}
char 类型的数据长度
在 C 语言中,char 类型占 1 字节,分为有符号与无符号两种;
在 Java 中,char 类型占 2 字节,只有无符号类型。
语言 | 类型 | 存储空间(字节) | 最小值 | 最大值 |
---|---|---|---|---|
Java | char | 2 | 0 | 65535 |
C | char(相当于signed char) | 1 | -128 | 127 |
C | signed char | 1 | -128 | 127 |
C | unsigned char | 1 | 0 | 255 |
2. String & StringBuilder & StringBuffer 的区别
操作效率
String 是不可变的,每次操作都会创建新的变量,而另外两个是可变的,不需要创建新的变量;另外,StringBuffer 的每个操作方法都使用 synchronized
关键字保证线程安全,增加了更多加锁 & 释放锁的时间。因此,操作效率排序为:StringBuilder
> StringBuffer
> String
。
线程安全
String 不可变,所以 String 和 StringBuffer 都是线程安全的,而 StringBuilder 是非线程安全的。
类型 | 操作效率 | 线程安全 |
---|---|---|
String | 低 | 安全(final) |
StringBuffer | 中 | 安全(synchronized) |
StringBuilder | 高 | 非安全 |
3. 为什么 String 设计为不可变类?
如何使得 String 不可变?
《Effective Java》中可变性最小化原则,阐述了不可变类的规则:
1、不对外提供修改对象状态的任何方法;
2、保证类不会被扩展(声明为 final 类或 private 构造器);
3、声明所有域为 final;
4、声明所有域为 private;
5、确保对于任何可变性组件的互斥访问。
为什么设计为不可变类?
1、相比可变类的不确定性,不可变类稳定可靠,适合作为散列表的键;
2、不可变对象本质是线程安全的,不需要同步;
3、风险:创建不可变类的对象代价可能很高,为提高性能使用可变配套类,StringBuilder 和 StringBuffer 可以理解为 String 的配置类。
提示: 反射可以破坏 String 的不可变性。
网友评论