1. String str = “abcdefg”;内存存储情况
最终结论:
变量str作为引用时放在栈中的
“abcdefg”会在堆中生成一个String对象(论证在下方)
变量 str引用这个堆中的String对象
分析论证:
测试代码:
package com.albert.test;
public classMain {
static String s_str = null;
static String s_str1= null;
public static void main(String[] args) {
// TODO Auto-generated method stub
Mainmain1= newMain();
main1.test();
System.out.println(s_str.length());
System.out.println(s_str == s_str1);// 返回值为TRUE,证明运行期,没有在生成多余的String对象
}
public void test(){
StringlocalStr= "abcdefg";
s_str = localStr;
s_str1 = localStr;
}
}
//输出结果长度为:7
分析:在test()函数中,localStr本身是一个引用,指向一个字符串常量。而s_str静态变量,获取到localStr的引用,两个变量指向同一个字符串“abcdefg”。
那常量“abcdefg”到底是不是要生成一个String对象呢?
假设localStr,s_str所引用的是常量字符串”abcdefg”,而非含有该字符串值的字符串对象。那么在输出语句哪里会报错,因为常量没有方法。但是程序正确的调用函数,返回字符串的长度,而java是全部面向对象的,所以 s_str引用的是一个对象,而非字符串常量,因为在test()中,s_str==localStr,所以localStr所引用也是对象,并且该对象包含的字符串值是”abcdefg”.
综合上述分析”abcdefg”,在某个时刻生成了一个String对象,那对象存放在哪里呢?如果说生成的对象放在栈中,那么当test()执行完后,该变量会被销毁,但是实际运行结果否定了这个假设,正确的调用了这个对象的方法。我发现,虽然是在局部函数中生成的对象,但在test()函数外,依然可以访问,这说明假设再次失败,该对象不是存在栈中,那究竟存在哪里呢?排除法,栈排除,静态池排除,剩下堆了,放在堆中,堆中对象特点:在没有引用时对象会被清理掉,程序中直到main()函数结束才释放对象。