字符串和字符数组之间的差异

时间:2013-08-17 12:25:49

标签: java

这些声明如何彼此不同?

String s="MY PROFESSION";
char c[]="MY PROFESSION";

每种情况下的内存分配情况如何?

7 个答案:

答案 0 :(得分:10)

要更正编译错误,请使用以下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";

字符数组

 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");
  • sbsbu都是可变的。 sb.replace(0, 1, 'B');
  • sbsbu都存储在堆
  • 可以修改尺寸/长度。 sb.append( '!');
  • StringBuffer的方法是同步的,而StringBuilder的方法不是

答案 1 :(得分:3)

第一个编译。第二个没有。

char[]就是:char类型的原始数组。它提供的只是length属性,以及在给定索引处获取和设置char的方法。

String是一个类型为java.lang.String的对象,它有很多用于操作字符串的有用方法。在内部,它使用char数组。

String的另一个重要特征是它是不可变的。您可以将String传递给任何方法,并确保此方法不会更改String的内容。 char数组不是这种情况。

关于内存,String会消耗更多的字节,但通常不应该指导您的设计决策:通常,使用char数组不是您应该做的。

答案 2 :(得分:1)

如果看到docs

     String str = "abc";

is equivalent to:

     char data[] = {'a', 'b', 'c'};  //  not 'abc'
     String str = new String(data);

更多String literals are very special in java

String内部由character数组支持。

答案 3 :(得分:1)

字符数组是可变的,换句话说,您可以通过覆盖该字符的内存位置来替换字符数组中的字符。

字符串不可变,换句话说,要“替换”字符串中的字符,您必须构建一个具有所需字符的新字符串(从旧字符串复制不变的部分)。

虽然这看起来很简单,但它对Thread(和对象)之间共享的能力有着深远的影响。可以在Threads之间安全地共享一个String,而无需额外检查以查看是否正在更改String(这可能会给Thread一个String的不一致性读取)。

其他优化也是可能的,因为字符串不能变异,你可以将相等操作重新连接为“按值等于”。这意味着“String factory”可以返回相同String的缓存副本,即使请求了两个不同的String对象,因为这两个对象的行为也不可能不同。

答案 4 :(得分:0)

char是一种原始类型。 String是一个类,其中实际数据在内部存储为字符数组

char c[]="MY PROFESSION";

会出现编译错误。

字符数组是内存中的连续存储,其中字符按顺序存储。

有关详细信息,请查看此Thread

答案 5 :(得分:0)

  

此声明如何相互区分?

您的第一行产生String个实例。你的第二行根本无效;也许你的意思是:

char[] c = {'M', 'Y', ' ', 'P', 'R', 'O', 'F', 'E', 'S', 'S', 'I', 'O', 'N'};

创建填充了这些字符的char[]

  

它的内存分配怎么样?

将字符串存储为String与将其存储为char[]的内存方式略有不同。但是有相似之处:两者都是对象,并且具有通常的对象开销。

但是,String内部拥有char[] ,因此String自然会消耗更多内存。此外,String有3个int字段(offsetcounthash),而char[]int个字段{ {1}}。

例如,将length存储为"MY PROFESSION"

  • 3个String字段: 12 字节
  • int字段: 8 字节
    • char[]字段: 4 字节
    • 对象开销: 8 字节
    • 13个字符: 26 字节
  • 对象开销: 8 字节

这大约是 66 字节。我说“约”,因为其中一些依赖于VM。正如您所看到的,长度为10的相应int仅消耗 38 字节。这里的内存差异可以忽略不计,所以你不必担心它(只需使用char[]!)。你试图存储的字符串越长,它变得越微不足道。

答案 6 :(得分:0)

char是基本类型,而String是类。 指定数量的字符串和字符串的数组是一组字符。

相关问题