繁体   English   中英

为什么char []比String更好? - Java

[英]Why char[] performs better than String ?- Java

参考链接: 文件IO调优 ,最后一节标题为“进一步调整”,作者建议使用char []来避免为文件中的n行生成String对象,我需要了解它是怎么做的

char[] arr = new char{'a','u','t','h', 'o', 'r'}

与...不同

String s = "author"

在内存消耗或任何其他性能因素方面? String对象是否内部存储为字符数组? 我觉得很傻,因为我以前从没想过这个。 :-)

在Oracle的JDK中, String有四个实例级字段:

  • 一个字符数组
  • 积分偏移量
  • 一个完整的字符数
  • 一个完整的哈希值

这意味着每个String引入了一个额外的对象引用( String本身),以及除了字符数组本身之外的三个整数。 (偏移和字符计数允许在通过String#substring()方法生成的String实例之间共享字符数组,这是一些其他Java库实现者所避免的设计选择。)除了额外的存储成本之外,还有一个更多级别的访问间接,更不用说使用String保护其字符数组的边界检查。

如果你能够分配和使用基本字符数组,那么就有空间可以保存。 在Java中这样做当然不是惯用的; 有理由提出明智的评论来证明这一选择的合理性,最好是提出分析差异的证据。

在这个例子中,你已经提到,这是因为只有一个字符数组被分配用于整个循环有。 它反复读入同一个数组,并在适当的位置处理它。

将其与使用readLine进行比较,后者需要在每次迭代时创建一个新的 String实例。 每个String实例将包含一些int字段和对包含实际数据的char[]的引用 - 因此每次迭代需要两个新实例。

我通常认为差异是微不足道的(与一个体面的GC非常有效地丢弃未使用的“年轻”对象)相比,读取数据所涉及的IO - 假设它来自磁盘 - 但我相信这是作者尝试的重点制作。

以下几个理由认为字符数组是Java中比String更好的选择:

说存储密码

1)由于字符串在Java中是不可变的,如果您将密码存储为纯文本,它将在内存中可用,直到垃圾收集器清除它并且因为字符串在字符串池中用于可重用性,它很可能会保留在内存中持续时间长,构成安全威胁。

由于任何有权访问内存转储的人都可以以明文形式找到密码,这是另一个原因,您应该始终使用加密密码而不是纯文本。

由于字符串是不可变的,所以不能更改字符串的内容,因为任何更改都会产生新的字符串,而如果你使用char [],你仍然可以将所有元素设置为空白或零。 因此,在字符数组中存储密码可以明显降低窃取密码的安全风险。

2)Java本身建议使用JPasswordField的getPassword()方法,该方法返回一个char []和不推荐使用的getText()方法,该方法以明文形式返回密码,说明安全原因。 很好地遵循Java团队的建议并坚持标准而不是反对它。

3)使用String时,总是存在在日志文件或控制台中打印纯文本的风险,但如果使用Array,则不会打印数组的内容而是打印其内存位置。 虽然不是一个真正的原因,但仍然有道理。

对于这个简单的程序

String strPassword="Unknown";
char[] charPassword= new char[]{'U','n','k','n','o','w','n'};
System.out.println("String password: " + strPassword);
System.out.println("Character password: " + charPassword);

输出:

String password: Unknown
Character password: [C@110b053

这就是为什么字符数组比String更好的选择,用于在Java中存储密码。 虽然使用char []还不够,但您需要擦除内容才能更安全。

希望这会有所帮助。

作者没有得到正确的理由。 in.readLine()的实际开销是在in.readLine()生成String时复制char []缓冲区。 在处理大数据时,额外的复制是最大的成本。

可以在JDK中对其进行优化,以便不需要额外的复制。

我的答案将集中在这个类似的线上的其他堆栈问题,其他人已经发布了更直接的答案。

还有其他类似的问题 ,建议似乎与使用StringBuilder有关。

如果您关注字符串集中,请查看此处描述的三种不同实现之间性能 使用另一个堆栈帖子可以为您提供一些额外的指示和示例,您可以尝试自己查看性能。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM