Java中的Char和String有什么区别?

9

作为AP计算机科学课程的一部分,我今年正在学习Java。阅读有关“Char”和“String”的内容时,我不明白为什么要使用“Char”,只能存储一个字符,而不是直接使用“String”,可以存储更多的字符。简而言之,“Char”只能存储单个字符,那么使用它的意义在哪里呢?


7
反过来思考你的问题:如果你只想存储一个字符,为什么要使用字符串? - MrLore
7
如果没有表示单个字符的方式,你该如何构建字符串? - Justin Niessner
互操作性也是一个考虑因素,byte、char和其他原始数据类型是大多数编程语言中常见的数据结构。 - MadProgrammer
如果没有 char,您将如何实现 String?一个 char 使用两个字节,一个空的字符串使用 24 个字节。如果可以使用 char,则效率要高得多。 - Peter Lawrey
8个回答

14

人们提到了内存问题,这是一个有效的问题,但我认为99%的情况下这不是非常重要的原因。 一个重要的原因是Java编译器会告诉你如果你犯了错误,这样就不需要自己去找出错误。

例如,如果你只想要一个变量来存储一个字符,你可以使用char来存储值,现在没有人可以将其他东西放在那里,否则便会出错。 如果你使用String,那么字符串中可能会有两个字符,即使你本打算永远不会出现这种情况也无济于事。 事实上,字符串中可能会有0个字符,这同样糟糕。 此外,所有使用String的代码都必须说“获取字符串的第一个字符”,而它可以简单地说“给我这个字符”。

一个比喻(可能你还不能理解)是,“为什么我要说一个Person有一个Name,而不是说Person有一个Name列表?” 原因相同。 如果你只希望一个Person有一个Name,那么给他一个Name列表会增加很多维护开销。


4
你可以考虑这个比喻:你需要一个苹果。你更喜欢手里拿着一个苹果,还是一个大盒子,能装更多的苹果,但只需要一个苹果?
在只需要一个字符的情况下,使用基本数据类型 char 比使用类 String 更加方便。同时它也会减少很多额外的开销,因为 String 类需要存储很多额外的方法和信息来处理包含多个字符的字符串,仅仅为了只有一个字符而使用 String 类就太过浪费了。如果您想从两种类型的变量中读取字符,则可以使用以下代码:
// initialization of the variables
char character = 'a';
String string = "a";
// writing a method that returns the character
char getChar()
{
    return character; // simple!
}
char getCharFromString()
{
    return string.charAt(0); // complicated, could fail if there is no character
}

如果您觉得这段代码很复杂,可以忽略它。结论是使用String来表示一个字符过于复杂。
基本上,String类用于需要多个字符的情况。您也可以创建一个char数组,但这样您将无法使用String类中有用的方法,例如.equals().length()方法。

你会有 length - Dennis Meng
除非您的数组比实际字符数量大,否则请勿使用@DennisMeng。动态数组等 - Cruncher
我想那是真的。 - Dennis Meng

3

String是对象。对象总是放在动态存储器上。存储一个单字符的字符串至少需要一打字节。

char(而不是Char)是基本类型。它们占用固定的空间(2个字节)。在需要处理单个字符的情况下,创建一个单字符字符串会浪费资源。此外,当您期望看到单个字符时,使用字符串将要求验证传递的数据确实只有一个字符。这在必须极快的情况下是不可接受的,例如基于字符的输入和输出。

总之,您需要一个char,因为:

  • 内存占用 - char比包含一个字符的String更小
  • 处理速度 - 创建对象会带来开销
  • 程序的可维护性 - 确定类型使您和代码读者知道应该存储在char变量中的数据类型更容易。

@Prabhaker 我对安全性并不是那么确定:由于其不可变性,String 也提供了相当不错的安全性。 - Sergey Kalinichenko
@Prabhaker 这是不同的观点 - 答案谈论的是字符数组,而不是单个字符。 - Sergey Kalinichenko

1

char 适用于只需要一个字符的情况,它占用更少的内存。还有其他多个应用程序可以使用单个字符。

char 是一种原始数据类型,而 string 是一个对象,它带来了更大的开销。

string 也由 char 组成,因此也要考虑这一点。


0

char 是一种原始类型,而 String 是一个真正的 Object。在某些性能要求较高的情况下,你可能只想使用原始类型。

另一个需要使用 char 的情况是当你编写 Java 1.0 并且被分配创建 String 类的任务时!

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
    /** The value is used for character storage. */
    private final char value[];

Java 1.0 中没有 Comparable 接口。 - Cruncher
@Cruncher 字符串自Java 1.0以来就存在了。我粘贴的实现是来自JDK 7。 - Rag
似乎你是在说,如果你必须在Java 1.0中编写它,那么这可以用来实现String。 - Cruncher
如果你必须在Java中实现String,你可以使用char数组,而且char数组在Java 1中就已经存在了。 - Rag

0

Java中的所有内容都可以转换为原始类型。您可以使用原始类型编写任何程序。因此,您需要一种某种极简主义的文本存储方式。Char实际上也只是一个字节,被解释为字符。

另外,如果您想循环遍历字符串中的所有字符,则可以执行以下操作:

char[] chArr = str.toCharArray();

for(int i = 0 ; i < chArr.length ; i++)
{
    //do something with chArr[i];
}

如果尝试从字符串中截取一个确切的字符,这将会更加笨拙。


0

因为char占用的内存较少!

而且,char被存储在内存中而不是作为引用值,因此从理论上讲,访问char更快(您以后会更了解)

***注意:当我刚开始编程时,我也曾有过同样的想法,即为什么要使用int,而可以使用long而不必担心大数。这告诉我你正在成为一个优秀的程序员!:)


需要明确的是,堆上的对象也是“存储在内存中”的,但会产生垃圾回收开销。本地基元类型分配在堆栈上,因此它们会自动消失。 - Rag
@BrianGordon 我的意思是强调对象必须存储引用值和它们的对象属性,这是双重麻烦。你提到的GC开销也很有道理。 - MobileMon

0

这里已经有很多答案了。虽然内存问题是合理的,但你必须意识到有时候你想直接操作字符。单词阶梯游戏,其中你尝试通过每次更改一个字符来将一个单词转换为另一个单词,这是我在编程课上必须完成的一个示例。拥有char类型可以让你一次操作一个字符。它还允许你将int分配给char,以映射到本地字符集。

你可以像char c = 97;这样做,这将打印出a。你可以做一些事情,比如递增一个字符从97到122,以打印出所有小写字符。有时这实际上是有用的。


哇,谢谢!我会记住这个建议,用在以后的项目中 :) - user2708074

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接