考虑:
String s1 = new StringBuilder("Cattie").append(" & Doggie").toString();
System.out.println(s1.intern() == s1); // true why?
System.out.println(s1 == "Cattie & Doggie"); // true another why?
String s2 = new StringBuilder("ja").append("va").toString();
System.out.println(s2.intern() == s2); // false
String s3 = new String("Cattie & Doggie");
System.out.println(s3.intern() == s3); // false
System.out.println(s3 == "Cattie & Doggie"); // false
Run Code Online (Sandbox Code Playgroud)
我糊涂了,为什么它们是由不同产生的返回值的String.intern()其中说:
调用intern方法时,如果池已经包含等于equals(Object)方法确定的此String对象的字符串,则返回池中的字符串。否则,将此String对象添加到池中,并返回对此String对象的引用。
特别是经过以下两个测试:
assertFalse("new String() should create a new instance", new String("jav") == "jav");
assertFalse("new StringBuilder() should create a new instance",
new StringBuilder("jav").toString() == …Run Code Online (Sandbox Code Playgroud) 我正在寻找一个可以列出已经内化的字符串的调试工具?理想情况下,我想添加一个标记并列出在该标记之后添加的字符串列表.
提前致谢.
尽管重用字符串常量和字面值,以下代码段会打印4个不同的哈希码.为什么字符串值没有插入注释元素?
public class Foo {
@Retention(RetentionPolicy.RUNTIME)
@interface Bar {
String CONSTANT = "foo";
String value() default CONSTANT;
}
public static void main(String[] args) throws Exception {
System.out.println(System.identityHashCode(Bar.CONSTANT));
System.out.println(System.identityHashCode(Foo.class.getMethod("test1").getAnnotation(Bar.class).value()));
System.out.println(System.identityHashCode(Foo.class.getMethod("test2").getAnnotation(Bar.class).value()));
System.out.println(System.identityHashCode(Foo.class.getMethod("test3").getAnnotation(Bar.class).value()));
}
@Bar
public void test1() {}
@Bar("foo")
public void test2() {}
@Bar(Bar.CONSTANT)
public void test3() {}
}
Run Code Online (Sandbox Code Playgroud) 我在网站上找到了如下代码.
string a = "xx";
string b = "xx";
string c = "x";
string d = String.Intern(c + c);
Console.WriteLine((object)a == (object)b); // True
Console.WriteLine((object)a == (object)d); // True
Run Code Online (Sandbox Code Playgroud)
在这里,再次投射到对象类型的目的是什么,因为a,b,d本身就是字符串的对象?
public static void main(String[] args) {
String a = new String("lo").intern();
final String d = a.intern();
String b = "lo";
final String e = "lo";
String c = "Hello";
System.out.println(b==a);//true
System.out.println(d==a);//true
System.out.println(e==a);//true
System.out.println(c=="Hel"+a); //why is this false? when e==a is true
System.out.println(c=="Hel"+d); //why is this false?
System.out.println(c=="Hel"+b); //why is this false?
System.out.println(c=="Hel"+e); //this is true
}
Run Code Online (Sandbox Code Playgroud)
这导致了
true
true
true
false
false
false
true
Run Code Online (Sandbox Code Playgroud)
表达式e==a为true意味着相同的引用.那么为什么最后一个表达式是真的但是第四个到最后一个表示c== "Hel"+a是假的?
这是一个非常特殊的Delphi问题(甚至可能是Delphi 2007特有的).我目前正在为实习字符串编写一个简单的StringPool类.作为一个优秀的小编码器,我还添加了单元测试,发现了令我困惑的东西.
这是实习的代码:
function TStringPool.Intern(const _s: string): string;
var
Idx: Integer;
begin
if FList.Find(_s, Idx) then
Result := FList[Idx]
else begin
Result := _s;
if FMakeStringsUnique then
UniqueString(Result);
FList.Add(Result);
end;
end;
Run Code Online (Sandbox Code Playgroud)
没有什么真正的花哨:FList是一个排序的TStringList,所以所有的代码都在查找列表中的字符串,如果它已经在那里它返回现有的字符串.如果它尚未出现在列表中,它将首先调用UniqueString以确保引用计数为1,然后将其添加到列表中.(我检查了结果的引用计数,并且在'hallo'被添加两次之后它是3,如预期的那样.)
现在来测试代码:
procedure TestStringPool.TestUnique;
var
s1: string;
s2: string;
begin
s1 := FPool.Intern('hallo');
CheckEquals(2, GetStringReferenceCount(s1));
s2 := s1;
CheckEquals(3, GetStringReferenceCount(s1));
CheckEquals(3, GetStringReferenceCount(s2));
UniqueString(s2);
CheckEquals(1, GetStringReferenceCount(s2));
s2 := FPool.Intern(s2);
CheckEquals(Integer(Pointer(s1)), Integer(Pointer(s2)));
CheckEquals(3, GetStringReferenceCount(s2));
end;
Run Code Online (Sandbox Code Playgroud)
这会将字符串'hallo'添加到字符串池两次并检查字符串的引用计数,并且s1和s2确实指向相同的字符串描述符.
每个CheckEquals都按预期工作,但最后一个.它失败,错误"预期:<3>但是:<4>".
那么,为什么引用计数为4?我原以为3:
这是Delphi 2007,因此字符串是AnsiStrings.
哦,是的,函数StringReferenceCount实现为:
function GetStringReferenceCount(const _s: AnsiString): integer;
var
ptr: …Run Code Online (Sandbox Code Playgroud) delphi string reference-counting delphi-2007 string-interning
我做了一些调查,以了解如何String.intern()在java中实现该方法.
我从Open JDK 6看了Intern池的C++实现,在那里我看到了一个简单的HashSet.对我而言,这意味着当有人试图实习时String,应该完成下一步:
String intern()方法返回它intern()方法返回很多人说str1.intern() == str2.intern()会比这更快str1.equals(str2).
但我看不出它应该更快的原因.
正如我所见,str1.equals(str2)我们总是有两个字符串比较char String.equals()方法中的char .
在这种情况下str1.intern() == str2.intern(),我们需要进行多少次比较或将字符串放入池中(对吧,它可以进行大量的比较,它们也是char比较的简单char)?
因此,str1.intern() == str2.intern()即使我们使用==比较字符串,我们也会有许多其他操作,例如前面描述的比较.
当我理解它时,我决定做一些基准测试.
第一个结果告诉我str1.intern() == str2.intern()比这更快str1.equals(str2).
此行为是由于该String.intern()方法是本机的,因此不应每次都解释它并且String.equals()是一个java方法.
所以我决定使用-Xcomp选项让JVM在启动时编译所有代码.
在那之后等于比实习生更快的速度.
我在Java 6和7上测试过它.
所以我的问题是你有没有看到在实际比较字符串比较速度增加的情况?我是怎么回事?
或者也许intern()只能帮助节省更多的免费记忆?
所以,我意识到我要提出的问题涉及到一次又一次被打死的话题,然而,即使在阅读了我能找到的所有答案和文档之后,我仍然对此感到困惑.字符串实习.也许是因为我对JVM缺乏了解; 也许这是由于Java 7中引入的变化使许多上述答案和文档贬值.无论哪种方式,我都被困住了,我希望有人可以帮助我更清楚地理解这个概念......
String a = "text";
String b = new String("text");
Run Code Online (Sandbox Code Playgroud)
在上面的例子中,我理解将创建两个String对象.我也明白在内存中只有一个包含序列't','e','x'和't'的char数组.但是,内存中的每个字符串对象实际存储在哪里?如果我读过的内容我已经正确阅读:变量的引用't', 'e', 'x', and 't'将存储在常量池中,而引用a将存储在堆中,对吧?如果是这种情况,我对实习池如何维护实习字符串感到困惑.它是否跟踪常量池中定义的字符串以及b从堆中手动内化(调用)的字符串?JVM是否创建常量池中定义的字符串对象并将它们加载到实习池中?我很困惑这一切是如何运作的......
再次,对于提出这样令人困惑/愚蠢的问题感到遗憾,这只是因为我对结构和内部工作方式相对较新,.intern()而且很多问题让我头晕目眩.谢谢!
public static void main(String[] args) {
String str1 = new StringBuilder("???").append("??").toString();
System.out.println(str1.intern() == str1);
String str2 = new StringBuffer("ja").append("va").toString();
System.out.println(str2.intern() == str2);
}
Run Code Online (Sandbox Code Playgroud)
结果:
true
false
Run Code Online (Sandbox Code Playgroud)
第一个打印true,第二个打印false.为什么结果不同?
>>> s1 = "spam"
>>> s2 = "spam"
>>> s1 is s2
True
>>> q = 'asdalksdjfla;ksdjf;laksdjfals;kdfjasl;fjasdf'
>>> r = 'asdalksdjfla;ksdjf;laksdjfals;kdfjasl;fjasdf'
>>> q is r
False
Run Code Online (Sandbox Code Playgroud)
应该s1 is s2给多少个角色False?限制在哪里?即,我问在python开始制作单独的副本之前,字符串必须有多长.
string-interning ×10
java ×7
string ×7
.net ×1
annotations ×1
c# ×1
constants ×1
delphi ×1
delphi-2007 ×1
equality ×1
heap ×1
jvm ×1
python ×1