如果我有类似下面的代码可行吗?
String b = "abc";
String c = "def";
for (int i=0;i<100000000;i++){
String a = b + c; // i got a different object , ahhh!
}
它如何影响系统?我们可以改进它吗?
不遵循字符串池的概念,因为我创建的字符串没有新的运算符我以1个对象结束,结果它创建了100000000个对象(我错了)但我没有unserstand如何(检查与 == 运营商)
例如
final String b = "abc";
final String c = "def";
for (int i=0;i<100000000;i++){
String a = b + c; //same object referred again and again
}
给出相同的对象,我可以使用 == 运算符
进行检查这两个示例都不遵循字符串池概念吗?为什么我的String变量的最终结果会改变不同对象或同一对象的结果。
答案 0 :(得分:6)
如果b
和c
未标记为final
,则编译器可能会假定在代码中的某个位置,可能会为这些变量分配不同的字符串。因此,当您编写a=b+c
时,编译器无法假设b
和c
的内容(它们甚至可能来自用户),因此必须将它们连接起来产生一个全新的字符串。
当它们为final
时,编译器可以确定b
总是"abc"
而c
始终是"def"
,甚至可能推断那个(b+c)=="abcdef"
,因此把它放在一个池中,或者只是在循环之前进行连接。
答案 1 :(得分:1)
当b
和c
为最终b + c
时,constant expression为{{3}}。这意味着+操作是在编译名称完成的。然后该行等同于
String a = "abcdef";
当b
和c
不是final时,它们的值不再被视为常量表达式,并且字符串连接在运行时完成,并且在每次迭代时都会创建新的String。
答案 2 :(得分:0)
它如何影响系统?我们可以改进它吗?
字符串是不可变的,即每次连接时它都会创建(或从池中重用)一个新的String对象。如果您正在进行循环连接,请使用StringBuilder对象。
String b = "abc";
String c = "def";
StringBuilder sb = new StringBuilder();
for (int i=0;i<100000000;i++){
sb.append(b);
sb.append(c);
}
result = sb.toString();
答案 3 :(得分:0)
“b”和“c”存储在池中。但每次都会创建“a”。使用StringBuilder来阻止它。
只是为了帮助您更好地理解它
Object b = new Object(); //b created only once
Object c = new Object(); //c created only once
for(int i = 0; i < 100500; i++) {
MyClass a = new MyClass(b, c); //a created each loop
}
与字符串相同。
正如弗拉德所说 - 如果字符串“b + c”每次都会产生新的对象,如果它们不是最终的