字符串和字符数组之间的区别

这些声明如何彼此不同?

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通过加载单个字符常量在堆栈帧中即时构建
  • c1c2是可变的,即可以修改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的方法则不是

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

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字段( offsetcounthash ),而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是类。 指定数量的字符串和字符串的数组是一组字符。