在学习视频中老师一直用画图的方式来讲解很生动,结合查阅此类的资料得到了以下的总结。Java的内存主要分为两种:一种是堆内存,一种是栈内存。
堆跟栈它们的共同点都是用来存储数据的地方,但是他们之间的作用还是有很大的区别:Java函数中定义的基本类型的变量以及对象的引用的变量都是函数的栈中存放,堆内存用来存放由new创建的对象和数组
栈内存:存储比较快,但是在栈中存储的数据大小与生存期是确定的,缺少了灵活性,不过在战中的数据是可以共享的,比如
int a = 5;
int b = 7;
b = 5;
Java虚拟机在编译的时候,首先处理的是int a = 5;先在栈内存里面创建一个a变量的引用,然后查找栈内存中是否存在值为5的地址,假若找不到则在栈的内存中分配一个值为5的地址,然后a引用指向5的地址。当在处理int b = 7引用时同理,接着b重新赋值 b = 5,这时栈内存已经存在了值为5的地址,这时b引用也指向a引用为5的地址。
以下面的例子再来看看堆内存:
String s = "abc";
String s1 = new String("abc");
System.out.println(s==s1);//输出的是false
看上去s应该是跟s1是相同但是为什么会输出false呢?
那是因为String s = "abc";在定义时,并没有创建String类的对象,但是这时String类的引用在栈内存却创建了,并且分配了一个值为abc的地址,上面有说到用new 创建的对象是存放在堆内存中,当在比较s==s1的时候是比较两个引用在内存中指向的地址是否相同,显然是不一样,一个存放堆内存一个存放栈内存。
值得注意的是:
(1)我们在使用诸如String str = "abc ";的格式定义时,总是以为我们创建了String类的对象str。但是这时错误的,不过可以确定的是,指向 String类的引用被创建了。
(2)使用String str = "abc ";的方式时,可以在一定程度上提高程序的运行速度,因为JVM会自动根据栈中的数据情况如果有了abc值的话就不用重新去分配一个地址了。而对于String str1 = new String( "abc ");不管是否堆内存是否存在abc的值,都必须创建新的对象。每一次都要创建新的对象。因此从效率来讲栈的运行效率要高于堆。
(3)当我们要比较两个对象值是否相同的时候应该用equal,以上面的两个变量来测试
System.out.println(str.equal(str1));//打印为true;
当要比较两个对象引用的时候就用==来表示。
System.out.println(str==str1);//打印为false;