对于字符串而言,对于在编译期创建的对象,也就是双引号定义的,保存在常量池中,对于在运行期创建的对象,也就是new的对象,保存在堆中。而且,使用equals相同的对象,常量池中只有一个,堆中有多个。我们举个例子:
String str="hello"; String str1 = "hello";String str2 = new String("hello");String str3 = new String("hello hi");
创建对象时候,str,str1,str2是存储在栈中,hello存储在常量池中,new String("hello")存储在堆中(int i=1;此时a和1都是存储在栈中)。此时编译处理是:String str="hello"; 现在栈中建立str引用,接着在栈中查找存放hello的地址,找到的话让str指向栈中的这个地址,没有的话常量池创造一个,然后str指向这个地址。 String str1 = "hello";时候,栈建立str1引用,然后再栈中找hello的存放地址并指向它(此时常良池中已存在hello,str1指向地址与str一致),String str2 = new String("hello");时,栈中建立str2引用,然后看常量池中存在hello,此时常量池已存在hello,堆中就只有new String("hello")这个一个对象。String str3= new String("hello hi");时栈中建立str3引用,此时常量池没有hello hi,则str3在常量池中创建一个hello hi 对象,然后再堆中创建一个new String("hello hi");对象。
由此可看出一个常见的问题:String str = new String("hello");创建了几个对象的答案:如果常量池中原来没有"hello"则产生两个对象,否则产生一个对象.