12

这些声明彼此有何不同?

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

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

4

7 回答 7

13

要更正编译错误,请替换为以下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 sb = new StringBuilder("MY PROFESSION");
StringBuffer sbu = new StringBuffer("MY PROFESSION");
  • sb和都是sbu可变的。sb.replace(0, 1, 'B');
  • sb和都sbu存储在堆中
  • 尺寸/长度可以修改。sb.append( '!');
  • StringBuffer的方法是同步的,而StringBuilder的方法不是
于 2013-08-17T13:34:34.267 回答
4

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

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

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

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

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

于 2013-08-17T12:31:28.823 回答
1

如果您看到文档

     String str = "abc";

is equivalent to:

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

更多的字符串文字在java中非常特殊

Stringcharacter内部数组支持。

于 2013-08-17T12:30:31.180 回答
1

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

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

虽然这看起来很简单,但它对线程(和对象)之间的共享能力产生了深远的影响。一个字符串可以在线程之间安全地共享,而无需额外检查字符串是否正在更改(这可能会给线程带来对字符串的不一致读取)。

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

于 2013-08-17T14:02:49.990 回答
0

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

char c[]="MY PROFESSION";

将给出编译错误。

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

查看此线程以获取更多详细信息。

于 2013-08-17T12:27:36.733 回答
0

该声明如何相互区分?

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

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

它创建了char[]充满这些字符。

它的内存分配呢?

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

但是, a在内部String拥有 a ,因此 a 自然会消耗更多内存。此外,有 3 个字段(和) ,而只有一个字段。char[] StringStringintoffsetcounthashchar[]intlength

例如,存储"MY PROFESSION"String

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

这大约是66个字节。我说“关于”是因为其中一些取决于 VM。如您所见,长度为 10的对应char[]仅消耗38个字节。这里的内存差异可以忽略不计,因此您不必担心(只需使用String!)。您尝试存储的字符串越长,它变得越不重要。

于 2013-08-17T12:33:41.177 回答
0

char 是原始类型,而 String 是类。由指定数量的字符串组成的数组,字符串是一串字符。

于 2017-08-26T11:32:05.440 回答