字符串和字符数组之间的区别
这些声明如何彼此不同?
String s="MY PROFESSION"; char c[]="MY PROFESSION";
在每种情况下内存分配怎么样?
要更正编译错误,请使用以下char[]
语句之一替换
String s = "MY PROFESSION"; char c1[] = "MY PROFESSION".toCharArray(); char c2[] = { 'M', 'Y', ' ', 'P', 'R', 'O', 'F', 'E', 'S', 'S', 'I', 'O', 'N' }; StringBuilder sb = new StringBuilder("MY PROFESSION"); StringBuffer sbu = new StringBuffer("MY PROFESSION");
以下部分将上述陈述相互比较
字符串常量
String s="MY PROFESSION";
- “MY PROFESSION”是一个常量并存储在String池中,请参阅Java的String常量池在哪里,堆或堆栈?
-
s
是不可变的,即String
内容完整无法修改。 - 字符串的大小/长度是固定的(不能追加)
字符数组
char c1[]="MY PROFESSION".toCharArray(); char c2[]={'M', 'Y', ' ', 'P', 'R', 'O', 'F', 'E', 'S', 'S', 'I', 'O', 'N'};
-
c1
保存String的基础数组的副本(通过System.arraycopy
)并存储在堆空间中 -
c2
通过加载单个字符常量在堆栈帧中即时构建 -
c1
和c2
是可变的,即可以修改Array
内容。c2[0]='B'
- 数组的大小/长度是固定的(不能追加)
StringBuilder / StringBuffer
StringBuilder sb = new StringBuilder("MY PROFESSION"); StringBuffer sbu = new StringBuffer("MY PROFESSION");
-
sb
和sbu
都是可变的。sb.replace(0, 1, 'B');
-
sb
和sbu
都存储在堆中 - 尺寸/长度可以修改。
sb.append( '!');
-
StringBuffer
的方法是同步的,而StringBuilder
的方法则不是
第一个编译。 第二个没有。
char[]
就是:char类型的原始数组。 它提供的只是一个length
属性,以及一种在给定索引处获取和设置char的方法。
String是一个java.lang.String类型的对象,它有很多用于操作字符串的有用方法。 在内部,它使用char数组。
String的另一个重要特性是它是不可变的。 您可以将String传递给任何方法,并确保此方法不会更改String的内容。 char数组不是这种情况。
关于内存,String会消耗更多的字节,但这通常不应该指导您的设计决策:通常,使用char数组不是您应该做的。
如果你看到文档 ,
String str = "abc"; is equivalent to: char data[] = {'a', 'b', 'c'}; // not 'abc' String str = new String(data);
更多字符串文字在java中非常特殊
String
由内部character
数组支持。
字符数组是可变的,换句话说,您可以通过覆盖该字符的内存位置来替换字符数组中的字符。
String是不可变的,换句话说,要“替换”字符串中的字符,您必须构建一个具有所需字符的新String(从旧String复制不变的部分)。
虽然这看起来很简单,但它对Thread(和对象)之间共享的能力有着深远的影响。 可以在Threads之间安全地共享一个String,而无需额外检查以查看是否正在更改String(这可能会给Thread一个String的不一致性读取)。
其他优化也是可能的,因为字符串不能变异,您可以将相等操作重新连接为“按值等于”。 这意味着“字符串工厂”可以返回相同String的缓存副本,即使请求了两个不同的String对象,因为这两个对象的行为也不可能不同。
char
是一种原始类型。 String
是一个类,其中实际数据在内部存储为字符数组
char c[]="MY PROFESSION";
会给出编译错误。
字符数组是内存中连续存储字符的连续存储。
查看此主题以获取更多详细信息。
这个声明如何相互区别?
您的第一行生成一个String
实例。 你的第二行无效; 也许你的意思是:
char[] c = {'M', 'Y', ' ', 'P', 'R', 'O', 'F', 'E', 'S', 'S', 'I', 'O', 'N'};
这会创建填充了这些字符的char[]
。
它的内存分配怎么样?
将字符串存储为字符串与将其存储为char[]
内存方式略有不同。 但是有相似之处:两者都是对象,并且具有通常的对象开销。
但是, String
在内部保存char[]
,因此String
自然会消耗更多内存。 此外, String
有3个int
字段( offset
, count
和hash
),而char[]
具有单个int
字段length
。
例如,将"MY PROFESSION"
存储为String
:
- 3个
int
字段: 12个字节 -
char[]
字段: 8个字节-
int
字段: 4个字节 - 对象开销: 8个字节
- 13个字符: 26个字节
-
- 对象开销: 8个字节
这大约是66个字节。 我说“约”因为其中一些依赖于VM。 正如您所看到的,长度为10的相应char[]
仅消耗38个字节。 这里的内存差异可以忽略不计,所以你不必担心它(只需使用String
!)。 你试图存储的字符串变得越长,它变得越微不足道。
char是原始类型,而String是类。 指定数量的字符串和字符串的数组是一组字符。