2011-12-02 147 views
2

如果我有下面的代码是可行的吗?字符串访问

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对象(我错了)但我没有unsendta如何(检查与==运营商)

例如

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 
} 

给同一个对象,我能请与==操作

不是T帽子这两个例子都遵循String pool的概念吗?为什么如果我有最终的我的字符串变量改变不同的对象或同一对象的结果。

+3

你想完成什么? – Pieter

+0

不错的一个:http://kaioa.com/node/59 – HRgiger

+0

这是一个面试问题,所以他检查了这个人在String上得到了什么,我无法得到最终的字符串变量和只是字符串变量的图片。 – linkin

回答

6

如果bc都没有标明final,编译器可能假定在某一时刻在代码中,可能会将不同的字符串分配给这些变量。因此,编写a=b+c时,编译器不能假设任何关于bc(它们甚至可能来自用户)的内容,因此它必须连接它们并产生一个全新的字符串。

当他们final,编译器可以知道肯定b总是​​和c总是"def",甚至可能推断(b+c)=="abcdef",因此把它放在一个池或干脆做串联循环之前。

+0

您在运行时获得的值将在String pool中保持(第一次),对不对?所以你怎么能得到10000000个对象,而你只能得到1个对象,而这个对象只能被一次又一次地引用! – linkin

+0

为什么它不是从游泳池重复使用?在创建一次之后 – linkin

+1

如果通过'javap -c'运行你的类,你会发现在编写'final'的情况下,编译器把''abcdef''作为一个常量。我不完全确定什么时候把东西放在字符串池中,但我的猜测主要是指编译时常量。我认为,如果每个字符串都进入池中,那将会导致惩罚,因为在检查它已经在池中之前,您仍然必须创建字符串(如果这有意义的话)。 – Vlad

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(); 
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”将每次产生新的对象,如果它们不是最终

1

bc是最后的b + cconstant expression。这意味着+操作是在编译名称完成的。然后,将线equivallent到

String a = "abcdef"; 

b时和c是非最终,它们的值不再被视为常量表达式和字符串连接是在运行时完成的,并创建新的字符串在每次迭代。