对Java中堆和栈的概念不太理解。请大神帮我解释下面代码的情况。请详细说明!谢谢
发布网友
发布时间:2022-03-01 01:40
我来回答
共2个回答
热心网友
时间:2022-03-01 03:09
首先明白==是比较地址的,在编译时,源码中的常量字符串会分派到字符串常量池中,a,b,y,x都是常量池中的引用。
c==x :因为b是一个不可变类型所以b+2在编译时可以确定是一个常量运行时不会变化,所以b+2可以直接引用常量池中的对象“hi2”
d==x :当然是不等的,因为a是一个变量,运行时很有可能会改变,当然此段代码我们可以看出它们事实是相等的,但是编译器还没有那么聪明,所以编译器不会直接处理,运行时再计算,jdk中的+操作是通过Stringbuffer实现的(可以看源码),也就是说运行时会在堆中分派新的对象,所以d是一个新的地址,一定和x指向的地址不同
a==y就不用说了,编译时就指向常量池中的同一个对象,运行时也没有变化过。追问谢谢你的回答。
在编译器看来,c和d都是一个不确定值的变量。那么c和d的值是存放在栈中,还是堆中?从运行结果推测来看,c==d为false。也就是说c和d的值不是同一个。
热心网友
时间:2022-03-01 04:27
Java中String是一个特殊的包装类数据有两种创建形式:
String s = "abc";
String s = new String("abc");
第一种先在栈中创建一个对String类的对象引用变量s,然后去查找"abc"是否被保存在字符串常量池中,如果没有则在栈中创建三个char型的值'a'、'b'、'c',然后在堆中创建一个String对象object,它的值是刚才在栈中创建的三个char型值组成的数组{'a'、'b'、'c'},接着这个String对象object被存放进字符串常量池,最后将s指向这个对象的地址,如果"abc"已经被保存在字符串常量池中,则在字符串常量池中找到值为"abc"的对象object,然后将s指向这个对象的地址。
第一种特点:JVM会自动根据栈中数据的实际情况来决定是否有必要创建新对象。
第二种可以分解成两步1、String object = "abc"; 2、String s = new String(object); 第一步参考第一种创建方式,而第二步由于"abc"已经被创建并保存到字符串常量池中,因此jvm只会在堆中新创建一个String对象,它的值共享栈中已有的三个char型值。
第二种特点:一概在堆中创建新对象,而不管其字符串值是否相等,是否有必要创建新对象。