是否存在字符数组比 Java 中的字符串更好的情况
Posted
技术标签:
【中文标题】是否存在字符数组比 Java 中的字符串更好的情况【英文标题】:Is there any scenario where character array is better than Strings in Java 【发布时间】:2019-02-26 13:29:44 【问题描述】:我觉得字符串可以在所有场景中替换字符数组。即使考虑到字符串的不变性特性,在适当范围内声明字符串和 java 的垃圾收集特性也应该可以帮助我们避免任何内存泄漏。我想知道是否存在应该使用字符数组而不是 Java 中的字符串的极端情况。
【问题讨论】:
这个问题太宽泛了,毫无意义。有案例吗?是的。这些是什么?这取决于。 生活的简单规则:任何以“是否有任何方式/场景/场景何时...”开头的问题的答案几乎总是“是” "。 如果使用字符串总是更好,他们为什么还要费心在语言中使用 char 数组?呵呵。 @MarcoBonelli: 好吧,你可以有所有类型的数组,所以只要它们还有char
类型,就会有char[]
(以及char[][]
和char[][][]
) 以及(即使它没有真正的用途)
恕我直言,这不是一个广泛的问题,也不是一个坏问题。使用String
在应用程序中存储字符串似乎很自然。在许多库中,我们看到 API 迫使我们在某些情况下使用字符数组。这有几个常见的原因,我想这就是操作所询问的这些动机。也许这个问题可以更清楚,但这是一个很好的问题。
【参考方案1】:
在存储安全敏感数据方面,字符数组比纯字符串有一些优势。这方面有很多资源,例如这个问题:Why is char[] preferred over String for passwords?(an answer by Jon Skeet 本人)。
总的来说,它归结为两件事:
您对String
在内存中的保留时间几乎没有影响。因此,您可能会通过内存转储泄露敏感数据。
在应用程序日志中以明文形式意外泄露敏感数据更有可能使用纯字符串
更多阅读:
Why we read password from console in char array instead of String https://www.codebyamir.com/blog/use-character-arrays-to-store-sensitive-data-java https://www.geeksforgeeks.org/use-char-array-string-storing-passwords-java/amp/ https://www.baeldung.com/java-storing-passwords https://javarevisited.blogspot.com/2012/03/why-character-array-is-better-than.html https://javainsider.wordpress.com/2012/12/10/character-array-is-better-than-string-for-storing-password-in-java/amp/【讨论】:
【参考方案2】:String 是一个类,而不是内置类型。它很可能通过在下面使用 char 数组来完成它的工作,但不能保证。 “我们不在乎它是如何实施的”。它具有对字符串有意义的方法,例如比较字符串。比较数组??唔。这样做真的没有意义。您可以检查它们是否相等,但小于或大于...
回到正题。一种情况是您想使用字符而不是字符串进行操作。例如,您有字母表并想要对它们进行排序。或 A-F 系统中的等级,您想要对它们进行排序。通常,将未连接的字符放在一起有意义(例如在消息字符串或文本消息中)是有意义的。您现在通常不需要对短信的字符进行排序,对吗?所以,你使用一个数组。 例如,要进行排序,您可以利用 Arrays.sort() 方法,而我认为没有一种方法可以对字符串进行排序。也许是第三部分库。
另一方面(与问题无关),如果您想经常修改字符串,可以使用 StringBuilder 。它的性能更好。
【讨论】:
【参考方案3】:您只需查看 JDK 核心 API 中使用 char[]
的方法即可。
如this one(java.io.Reader):
public int read(char[] cbuf)
throws IOException
将字符读入数组。此方法将阻塞,直到某些输入可用、发生 I/O 错误或到达流的末尾。
参数:
cbuf - 目标缓冲区 返回: 读取的字符数,如果已到达流的末尾,则为 -1 抛出: IOException - 如果发生 I/O 错误
他们要求您传入 char[]
以用作将结果写入的缓冲区,而不是返回 String
。原因是效率。
【讨论】:
【参考方案4】:您可能知道 String 是不可变的,以及 Substring 如何导致 Java 中的内存泄漏。 由于字符串在 Java 中是不可变的,如果您将密码存储为纯文本,它将在内存中可用,直到垃圾收集器将其清除,并且由于字符串在字符串池中用于可重用性,因此很有可能它会长时间保留在内存中,构成安全威胁。因为任何有权访问内存转储的人都可以以明文形式找到密码。由于字符串是不可变的,因此无法更改字符串的内容,因为任何更改都会产生新的字符串,而如果您使用 char[],您仍然可以将他的所有元素设置为空白或零。因此,将密码存储在字符数组中显然可以降低窃取密码的安全风险。
【讨论】:
我正在阅读与该主题相关的 SO 线程,并发现与密码安全相关的有趣评论。 “如果有人可以访问应用程序运行的内存,那么是否将密码存储在字符串中是目前最小的问题”以上是关于是否存在字符数组比 Java 中的字符串更好的情况的主要内容,如果未能解决你的问题,请参考以下文章
什么情况下用+运算符进行字符串连接比调用StringBuffer/StringBuilder对象的append方法连接字符串性能更好?