[英]“a string with a char: ” + 'c' better or worse than “a string with a char: ” + “c”?
[英]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.