• final、finally、finalize三者的区别?
  • 类似:
  • throw 和 throws
  • Collection 和 Collections
  • String 、StringBuffer、StringBuilder
  • ArrayList 、 LinkedList
  • HashMap 、LinkedHashMap
  • 重写、重载
  • 结构不相似的:
  • 抽象类、接口
  • == 、 equals()
  • sleep()、wait() ```java //前置知识: //1)从DK1.7开始,JVM就将常量池从方法区中移到堆中,但跟普通的变量对象不在一起,是一个专门的区域; //2)从JDK源码知,String底层由字节数组value实现,且其被final修饰,故而String是一个不可变对象,因此它可共享; //3)通过new方式产生的String对象在堆里(非常量池),而例如【String str1=”ab”;】这样直接生成的String对象是在常量池里构建的; public class String_StringBuffer内存分配问题 { public static void main(String[] args) { //完成了3件事:1)堆里构建了一个byte[97,98]数组,以存储【ab】的ASCII码值,假设其地址值为【0x11】; //2)在常量池里构建了一个String对象,假设其地址值为【0x22】,随后将【0x11】赋值给了此对象的value属性(即value指向数组[97,98]); //3)在栈里开辟一个变量区(str1),并给其赋值为【0x22】(即str1指向常量池里的String对象) String str1=”ab”; //完成了2件事:1)栈里开辟一个变量区(str2);2)将str1的值【0x22】赋值给str2(即此时,str1和str2同时指向常量池里的String对象) String str2=str1; //完成了4件事:1)堆里构造了一个byte[99,100]数组,以存储【cd】的ASCII码值; //2)堆里构造了一个byte[97,98,99,100]数组,以存储拼接后的【abcd】的ASCII码值,假设其地址为【0x33】; //3)堆里构造了一个String对象(由于该对象是由变量和常量进行拼接而成,因此该对象不在常量池里构建),其value被赋值为【0x33】; //4)将栈里变量str1的值改为【0x33】; str1=str1+”cd”; //从上可知,str1所指地址是【0x33】,内容是【abcd】,而str2不变,所指地址是【0x22】,其内容是【ab】 System.out.println(str1);//所以打印结果是:abcd System.out.println(str2);//所以打印结果是:ab System.out.println(str1==str2);//【0x33】!=【0x22】

//完成了3件事:1)堆里构造了一个字节数组[49,50],假设其地址是【0x44】,用于存放字符串【12】的ASCII码值; //2)堆里构造了一个StringBuffer对象,假设其地址为【0x55】,其属性value的值被赋值为【0x44】,即value指向字节数组; //3)栈上开辟一个变量strBuf1,被赋值为【0x55】,即strBuf1指向上述StringBuffer对象; StringBuffer strBuf1=new StringBuffer(“12”); //完成了3件事:栈上开辟一个变量strBuf2;2)strBuf2被赋值为【0x55】,即strBuf2也指向上述StringBuffer对象; StringBuffer strBuf2=strBuf1; System.out.println(strBuf1==strBuf2);//由于【0x55】==【0x55】,所以输出true //完成了1件事:将 字符串【34】的ASCII码值[51,52]添加到【0x44】所指的字节数组[49,50]的后面, // 由于没超出空间,所以该字节数组所以不会扩容 strBuf1.append(“34”); System.out.println(strBuf1);//strBuf1指向位置没变 System.out.println(strBuf2);//strBuf2指向位置也没变 System.out.println(strBuf1==strBuf2);//由于【0x55】==【0x55】,所以输出true }

```