Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/341.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
java中的字符串池_Java_String_Pool - Fatal编程技术网

java中的字符串池

java中的字符串池,java,string,pool,Java,String,Pool,Java有字符串池,由于字符串类的对象是不可变的 但我的问题是正确的- 制作字符串池需要什么? 为什么string类不像其他类那样保留自己的值 JVM内部是否需要一些字符串,或者这是性能优势。如果是,怎么做?池是可能的,因为字符串是不可变的。但是字符串的不变性并不是仅仅因为这个池才决定的。不变性还有许多其他好处。顺便说一句,Double也是不可变的,没有Double池 对字符串池的需求是减少保存程序使用的所有字符串文本(以及插入的字符串)所需的内存,因为这些文本很有可能在程序的许多地方被多次使用

Java有字符串池,由于字符串类的对象是不可变的

但我的问题是正确的-

制作字符串池需要什么?

为什么string类不像其他类那样保留自己的值


JVM内部是否需要一些字符串,或者这是性能优势。如果是,怎么做?

池是可能的,因为字符串是不可变的。但是字符串的不变性并不是仅仅因为这个池才决定的。不变性还有许多其他好处。顺便说一句,
Double
也是不可变的,没有Double池

对字符串池的需求是减少保存程序使用的所有字符串文本(以及插入的字符串)所需的内存,因为这些文本很有可能在程序的许多地方被多次使用。同一个字符串文本没有数千个副本,而只对同一个字符串有数千个引用,这减少了内存使用


请注意,String类与其他类没有什么不同:它拥有自己的char数组。但是,当调用子字符串时,它也可能与其他字符串实例共享它。

当我们看到必须创建新的字符串文本时,它首先检查池中是否有相同的字符串,如果发现没有创建新的字符串文本,引用现有字符串。

将字符串设置为不可变的好处在于安全特性。阅读下文

为什么字符串在Java中是不可变的

虽然,性能也是一个原因(假设您已经知道维护的内部字符串池,以确保同一字符串对象被多次使用,而无需多次创建/重新声明),但字符串在Java中保持不变的主要原因是“安全性”。惊讶让我们了解原因

假设您需要打开一个安全文件,该文件要求用户对自己进行身份验证。假设有两个名为“user1”和“user2”的用户,他们分别有自己的密码文件“password1”和“password2”。显然,“user2”不应该有权访问“password1”文件

正如我们所知,Java中的文件名是使用字符串指定的。即使创建“File”对象,也只能将文件名作为字符串传递,并且该字符串作为其成员之一保存在文件对象中

如果字符串是可变的,“user1”可以使用他的凭据登录,然后在JVM实际调用本机操作系统打开文件之前,设法将其密码文件名(字符串对象)的名称从“password1”更改为“password2”。这将允许“user1”打开user2的密码文件。可以理解,这将导致Java中存在一个巨大的安全漏洞。我知道这里有这么多的“可能”,但您肯定会同意,这将打开一扇门,允许开发人员故意或非故意破坏许多资源的安全性

由于字符串是不可变的,JVM可以确保相应文件对象的filename实例成员将一直指向相同的未更改的“filename”字符串对象。作为File类中“final”的“filename”实例成员无论如何不能修改为指向任何其他字符串对象,该字符串对象指定除预期文件以外的任何其他文件(即用于创建文件对象的文件)

什么是需要使字符串池

创建时,字符串对象存储在堆中,在构造函数中发送的字符串文本存储在SP中。这就是为什么使用字符串对象不是一个好的做法。因为它创建了两个对象

String str = new String("stackoverflow");
上面的str和引用str一起保存在堆中,构造函数“stackoverflow”中的字符串文本存储在字符串池中。这对性能不利。两件物品被装箱

流程:创建字符串文本->JVM在字符串池中查找值,以查找是否存在相同的值(不返回任何对象)->值未找到->字符串文本被创建为新对象(内部带有新关键字)->但现在未发送到堆,而是在字符串池中发送

区别在于使用new关键字创建对象的位置。如果它是由程序员创建的,它会毫不延迟地直接发送堆中的对象。如果是在内部创建的,则发送到字符串轮询。这是通过intern()方法完成的。intern()是在声明字符串文字时在内部调用的。此方法正在SP中搜索与返回现有字符串对象的引用或/和将对象发送到SP相同的值

使用new创建字符串obj时,不会调用intern(),对象存储在heap中。但是您可以对字符串obj调用intern():String str=new String().intern();现在str对象将存储在SP中。 例:


实际上,编译器与此无关。文本放在类文件中,并在加载类时由池解析。因此,如果找到匹配项,则池中的字符串不会被引用?这不是真正的安全原因。如果字符串在Java中是可变的,则File类只需要将带有文件名的字符串复制到新的string对象中。它只是一个性能特性,不需要这种复制(对于程序员来说,这是一个方便的特性,他们不会忘记所需的复制)。Double也是不可变的,并且没有Double池—很好的选择:)谢谢“程序生成的字符串文字”是什么意思?你是说JVM在内部生成许多类似的字符串,即使应用程序不处理文本,也不显式地创建许多字符串对象?不,我的意思恰恰相反:如果200个类在其代码中使用字符串文本
,那么只会创建一个实例,存储在字符串池中,然后
String s1 = new String("hello").intern();
String s2 = "hello";
System.out.println(s1 == s2); // true , because now s1 is in SP