什么是字符串实习在Java,当我应该使用它,为什么?
当前回答
因为字符串是对象,而且Java中的所有对象总是只存储在堆空间中,所以所有字符串都存储在堆空间中。然而,Java将不使用new关键字创建的字符串保存在堆空间的一个特殊区域中,这个区域称为“字符串池”。Java将使用new关键字创建的字符串保存在常规堆空间中。
The purpose of the string pool is to maintain a set of unique strings. Any time you create a new string without using the new keyword, Java checks whether the same string already exists in the string pool. If it does, Java returns a reference to the same String object and if it does not, Java creates a new String object in the string pool and returns its reference. So, for example, if you use the string "hello" twice in your code as shown below, you will get a reference to the same string. We can actually test this theory out by comparing two different reference variables using the == operator as shown in the following code:
String str1 = "hello";
String str2 = "hello";
System.out.println(str1 == str2); //prints true
String str3 = new String("hello");
String str4 = new String("hello");
System.out.println(str1 == str3); //prints false
System.out.println(str3 == str4); //prints false
== operator is simply checks whether two references point to the same object or not and returns true if they do. In the above code, str2 gets the reference to the same String object which was created earlier. However, str3 and str4 get references to two entirely different String objects. That is why str1 == str2 returns true but str1 == str3 and str3 == str4 return false . In fact, when you do new String("hello"); two String objects are created instead of just one if this is the first time the string "hello" is used in the anywhere in program - one in the string pool because of the use of a quoted string, and one in the regular heap space because of the use of new keyword.
字符串池是Java通过避免创建包含相同值的多个String对象来节省程序内存的方法。可以使用string的intern方法从字符串池中获取使用new关键字创建的字符串的字符串。它被称为字符串对象的“实习”。例如,
String str1 = "hello";
String str2 = new String("hello");
String str3 = str2.intern(); //get an interned string obj
System.out.println(str1 == str2); //prints false
System.out.println(str1 == str3); //prints true
OCP Java SE 11程序员,Deshmukh
其他回答
字符串实习是编译器的一种优化技术。如果在一个编译单元中有两个相同的字符串字面值,则生成的代码将确保在程序集中为该字面值(双引号括起来的字符)的所有实例只创建一个字符串对象。
我来自c#背景,所以我可以通过给出一个例子来解释:
object obj = "Int32";
string str1 = "Int32";
string str2 = typeof(int).Name;
以下比较的输出:
Console.WriteLine(obj == str1); // true
Console.WriteLine(str1 == str2); // true
Console.WriteLine(obj == str2); // false !?
注1:对象通过引用进行比较。
注2:typeof (int)。名称由反射方法求值,因此在编译时不会求值。这里这些比较是在编译时进行的。
结果分析: 1) true,因为它们都包含相同的文字,所以生成的代码将只有一个引用“Int32”的对象。见注1。
2) true,因为两个值的内容都是相同的。
3) FALSE,因为str2和obj没有相同的字面值。见注2。
面试中有一些“很吸引人”的问题,比如为什么你的成绩和别人一样!如果执行下面的代码段。
String s1 = "testString";
String s2 = "testString";
if(s1 == s2) System.out.println("equals!");
如果你想比较字符串,你应该使用equals()。上面的代码将输出等于,因为testString已经被编译器为你进行了存储。您可以自己使用intern方法实习字符串,如前面的答案....所示
因为字符串是对象,而且Java中的所有对象总是只存储在堆空间中,所以所有字符串都存储在堆空间中。然而,Java将不使用new关键字创建的字符串保存在堆空间的一个特殊区域中,这个区域称为“字符串池”。Java将使用new关键字创建的字符串保存在常规堆空间中。
The purpose of the string pool is to maintain a set of unique strings. Any time you create a new string without using the new keyword, Java checks whether the same string already exists in the string pool. If it does, Java returns a reference to the same String object and if it does not, Java creates a new String object in the string pool and returns its reference. So, for example, if you use the string "hello" twice in your code as shown below, you will get a reference to the same string. We can actually test this theory out by comparing two different reference variables using the == operator as shown in the following code:
String str1 = "hello";
String str2 = "hello";
System.out.println(str1 == str2); //prints true
String str3 = new String("hello");
String str4 = new String("hello");
System.out.println(str1 == str3); //prints false
System.out.println(str3 == str4); //prints false
== operator is simply checks whether two references point to the same object or not and returns true if they do. In the above code, str2 gets the reference to the same String object which was created earlier. However, str3 and str4 get references to two entirely different String objects. That is why str1 == str2 returns true but str1 == str3 and str3 == str4 return false . In fact, when you do new String("hello"); two String objects are created instead of just one if this is the first time the string "hello" is used in the anywhere in program - one in the string pool because of the use of a quoted string, and one in the regular heap space because of the use of new keyword.
字符串池是Java通过避免创建包含相同值的多个String对象来节省程序内存的方法。可以使用string的intern方法从字符串池中获取使用new关键字创建的字符串的字符串。它被称为字符串对象的“实习”。例如,
String str1 = "hello";
String str2 = new String("hello");
String str3 = str2.intern(); //get an interned string obj
System.out.println(str1 == str2); //prints false
System.out.println(str1 == str3); //prints true
OCP Java SE 11程序员,Deshmukh
通过使用堆对象引用,如果我们想要对应SCP对象引用,我们应该使用intern()方法。
例子:
class InternDemo
{
public static void main(String[] args)
{
String s1=new String("smith");
String s2=s1.intern();
String s3="smith";
System.out.println(s2==s3);//true
}
}
实习生流程图
针对Java 8或以上版本进行更新。 在Java 8中,永久生成(Permanent Generation)空间被移除,并被元空间(Meta space)取代。String池内存被移动到JVM的堆中。
与Java 7相比,堆中的String池大小增加了。因此,您可以为内部化的字符串提供更多的空间,但整个应用程序的内存却较少。
还有一件事,你已经知道在Java中比较2个对象的引用时,'=='用于比较对象的引用,'equals'用于比较对象的内容。
让我们检查一下这段代码:
String value1 = "70";
String value2 = "70";
String value3 = new Integer(70).toString();
结果:
Value1 == value2——> true
Value1 == value3——> false
Value1.equals (value3)——> true
Value1 == value3.intern()——> true
这就是为什么你应该使用'equals'来比较2个String对象。这就是intern()的用处所在。
推荐文章
- 我应该如何从字符串中删除所有的前导空格?- - - - - -斯威夫特
- 如何格式化Joda-Time DateTime仅为mm/dd/yyyy?
- 如何在POM.xml中引用环境变量?
- 如何在android中复制一个文件?
- 将整数转换为字符串,以逗号表示千
- 将JavaScript字符串中的多个空格替换为单个空格
- 接口方法的最终参数-有什么意义?
- Java中的@UniqueConstraint注释
- printf()和puts()在C语言中的区别是什么?
- 如何在清洁模式下运行eclipse ?如果我们这样做会发生什么?
- 获取java.lang.ClassNotFoundException: org.apache.commons.logging.LogFactory异常
- Java中的正则表达式命名组
- c#和Java的主要区别是什么?
- 什么是NullPointerException,我如何修复它?
- 在Java中使用“final”修饰符