我读过许多关于字符串实习的文章。
如果我创建一个String对象
方法1
String str= new String("test")
2在堆中创建一个对象,在字符串池中创建另一个对象。
方法2,如果未执行方法1
String str= new String("test").intern()
它将创建一个字符串frpoom堆到字符串池的副本。将创建多少个对象。我猜3.One将在堆中,其他在池中和一个“test”文字。
在这两种情况下哪一个都有资格获得GC。我见过有人说2会被创建,但我无法理解为什么?
方法3
String s= new String("test")
String s1=s.intern()
除了s指向堆对象和s1到pool对象之外,它做同样的事情,并且它们都没有资格获得Gc。
我的理解是否正确?我对这个概念感到很困惑。
答案 0 :(得分:1)
如果我创建一个String对象
std::set<CString>
在堆中创建对象,在字符串池中创建其他对象。
一个字符串由两个对象组成,std::set<CString, std::less<CString>, std::allocator<CString>>
和std::less<CString>
在某些Java版本中,它可能是ThingComparator
或实际上是struct ThingComparator {
...
};
template<typename Comparator>
static void Blah(std::set<CString, Comparator>& things) {
...
}
...
std::set<CString, ThingComparator> things;
Blah(things);
,后来被替换由 String str= new String("test")
。这意味着可以创建4个,也许可以创建5个对象,除非字符串文字的字符串已经存在,在这种情况下,对于Java 7更新4+,它是2,在此之前,String
将被共享,因此它可能是三个对象或只有一个。
char[]
这是完全相同的,除非,如果调用足够的话,可以在堆栈上分配byte[]
,你可能会发现只创建了char []`,这不能放在堆栈上,此时此刻。将来,这也可能会被优化掉。
在这两种情况下哪一个都有资格获得GC。我见过有人说2会被创建,但我无法理解为什么?
答案是1到4,具体取决于具体情况。所有这些都有资格收集,除非它们在某处被强烈引用。
答案 1 :(得分:0)
需要注意的是
String
文字自动实习,intern()
方法用于使用新String()
构建的字符串
Strings
(更具体地说,字符串对象)如果变得无法访问,将被垃圾收集,就像任何其他java对象一样。
字符串literals
通常不是垃圾收集的候选者。从Object到该文字将有一个隐式引用。
point#3
的原因是如果可以在方法中使用文字来构建String
,只要该方法可以执行。
答案 2 :(得分:0)
String intern()方法:
字符串比较最常用的方法是equals()
和equalsIgnoreCase()
方法。但是,对于大字符序列,这些方法可能需要大量内存。 Java String intern()
方法帮助我们提高两个字符串之间的比较性能。
intern()
方法应用于String对象时,返回对此对象的引用(来自Java所生成的字符串的哈希集),该引用与原始对象具有相同的内容。因此,如果代码对多个String对象使用intern()
方法,那么我们的程序将使用更少的内存,因为它将在这些字符串之间的比较中重用对象的引用。
请记住,Java会自动实现字符串文字。这意味着intern()
方法将用于使用新String()
构造的字符串。
示例:
JavaStringIntern.java
package com.javacodegeeks.javabasics.string;
public class JavaStringIntern {
public static void main(String[] args) {
String str1 = "JavaCodeGeeks";
String str2 = "JavaCodeGeeks";
String str3 = "JavaCodeGeeks".intern();
String str4 = new String("JavaCodeGeeks");
String str5 = new String("JavaCodeGeeks").intern();
System.out.println("Are str1 and str2 the same: " + (str1 == str2));
System.out.println("Are str1 and str3 the same: " + (str1 == str3));
System.out.println("Are str1 and str4 the same: " + (str1 == str4)); //this should be "false" because str4 is not interned
System.out.println("Are str1 and str4.intern() the same: " + (str1 == str4.intern())); //this should be "true" now
System.out.println("Are str1 and str5 the same: " + (str1 == str5));
}
}
Output:
Are str1 and str2 the same: true
Are str1 and str3 the same: true
Are str1 and str4 the same: false
Are str1 and str4.intern() the same: true
Are str1 and str5 the same: true