栈与堆都是Java用来在Ram(内存)中存放数据(包括基本类型数据和包装类数据)的地方。与C++不同,Java自动管理栈和堆,程序员不能直接地设置栈或堆。
栈stack:存放基本类型的变量数据和对象的引用;
存取速度比堆要快,但是存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。
如int a = 3; 这里的a是一个指向int类型的引用;
存在栈中的数据可以共享
堆heap:存放所有new出来的对象和数组
堆的优势是可以动态地分配内存大小,Java的垃圾收集器会自动收走这些不再使用的数据,缺点是,由于要 在运行时动态分配内存,存取速度较慢。
(在堆中产生了一个数组或对象后,还可以在栈中定义一个特殊的变量,让栈中这个变量的取值等于数组或对象在堆内存中的首地址,栈中的这个变量就成了数组或对象的引用变量。)
常量池(字符串缓冲池):存放字符串常量对象
题1:String s=new String(“china”)创建了几个String Object
答案:2个
解析:
.
对于通过new产生一个字符串(假设为”china”)时,会先去常量池中查找是否已经有了”china”对象,如果没有则在常量池中创建一个此字符串对象,然后堆中再创建一个常量池中此”china”对象的拷贝对象。
题2:成员变量和局部变量的储存
成员变量:方法外部,类的内部定义的变量;
存储在堆中的对象里面,由垃圾回收器(GC)负责回收
局部变量:方法或语句块内部定义的变量。
局部变量必须初始化。
形式参数是局部变量
局部变量的数据存在于栈内存中。
栈内存中的局部变量随着方法的消失而消失。
题3:String str = "abc";与String str =new String("abc")的区别
String str ="abc":一定程度上提高程序的运行速度。
JVM首先检查常量池中是否存在“abc”, 如果存在则直接将"abc"赋给str,如果不存在则会先在常量池中新建一个字符串"abc",然后再将其赋给str。这个时候,只是在栈中创建了一个指向String类的”abc”对象的引用变量str。对象不一定被创建!
因此,JVM会自动根据栈中数据的实际情况来决定是否有必要创建新对象。
String str = new String("abc"):new的话一概在堆中创建新对象,加重程序的负担。
题4:==与equals的区别
==:比较两个变量的值是否相等(即变量所指向的对象是否是一个对象),多用于基本类型的数据的比较
equals:比较两个独立对象的内容是否相等(前提是两个对象的类型要相同)。
问题一:JVM创建了两个引用str1和str2,但只创建了一个对象,而且两个引用都指向了这个对象。
String str1 = "abc";
String str2 = "abc";
System.out.println(str1==str2); //true
问题二:赋值的变化导致了类对象引用的变化,str1指向了另外一个新对象!而str2仍旧指向原来的对象。当我们将str1的值改为"bcd"时,JVM发现在栈中没有存放该值的地址,便开辟了这个地址,并创建了一个新的对象,其字符串的值指向这个地址。
String str1 = "abc";
String str2 = "abc";
str1 = "bcd";
System.out.println(str1==str2); //false
问题三:用new的方式是生成不同的对象。每一次生成一个。因此两个不同的对象
String str1 =new String ("abc");
String str2 =new String ("abc");
System.out.println(str1==str2); // false
问题四:java 重载了“+”,查看java字节码可以发现“+”其实是调用了StringBuilder 所以使用了“+”其实是生成了一个新的对象。所以(s3 == s4)打印false
String s1 = "ja";
String s2 = "va";
String s3 = "java";
String s4 = s1 + s2;String s5 = "ja" +"va";
System.out.println(s3 == s4);//falseSystem.out.println(s3 == s5);// true
System.out.println(s3.equals(s4));//true
问题五:str3这个对象的引用直接指向str1所指向的对象(注意,str3并没有创建新对象)。
String str1 = "abc";
String str2 = "abc";
str1 = "bcd";
String str3 = str1;
String str4 = "bcd";
System.out.println(str1 == str4); //true