question1:String s1="aa";创建了几个String对象?String s2=new String("aa");又创建了几个String对象?两句话有什么区别?
question2: String s1="aa" ;String s2="aa" 创建了几个String对象?String s1=new String("aa"); String s2=new String("aa");又创建了几个对象??question3:
//////test equals and == Test1.java
class Test1{
pulic static void main(String []args){
String s1=new String("aa");
String s2=new String("aa");
System.out.println("s1==s2"+(s1==s2));
System.out.println("s1.equals(s2)"+s1.equals(s2));
}
}
--------------result:---------------s1==s2false
s1.equals(s2)true
class Test2{
pulic static void main(String []args){
String s1="aa"
String s2="aa"
System.out.println("s1==s2"+(s1==s2));
System.out.println("s1.equals(s2)"+s1.equals(s2));
}
}
------------result--------s1==s2true
s1.equals(s2)trueDo explain why it is so here ????
question2: String s1="aa" ;String s2="aa" 创建了几个String对象?String s1=new String("aa"); String s2=new String("aa");又创建了几个对象??question3:
//////test equals and == Test1.java
class Test1{
pulic static void main(String []args){
String s1=new String("aa");
String s2=new String("aa");
System.out.println("s1==s2"+(s1==s2));
System.out.println("s1.equals(s2)"+s1.equals(s2));
}
}
--------------result:---------------s1==s2false
s1.equals(s2)true
class Test2{
pulic static void main(String []args){
String s1="aa"
String s2="aa"
System.out.println("s1==s2"+(s1==s2));
System.out.println("s1.equals(s2)"+s1.equals(s2));
}
}
------------result--------s1==s2true
s1.equals(s2)trueDo explain why it is so here ????
『问』
1.String s1="aa";创建了几个String对象?
『解答』
只创建一个String对象,并且引用s1和它所指的对象本身都存储在栈(stack)中。
『问』
2.String s2=new String("aa");又创建了几个String对象?两句话有什么区别?
『解答』
创建了一个Sting对象,并且引用s2存储在栈(stack)中,而它所指的对象本身存储在堆(heap)中。question2:
『问』
1.String s1="aa" ;String s2="aa" 创建了几个String对象?String
『答』
创建了一个对象,栈中的引用s1和s2都指向栈中的同一个对象。
『问』
2.s1=new String("aa"); String s2=new String("aa");又创建了几个对象??
『答』
创建了两对象,栈中的引用s1和s2分别指向堆中不同的对象。
(1)先定义一个名为str的对String类的对象引用变量:String str;
(2)在栈中查找有没有存放值为"abc"的地址,如果没有,则开辟一个存放字面值为"abc"的地址,接着创建一个新的String类的对象o,并将o 的字符串值指向这个地址,而且在栈中这个地址旁边记下这个引用的对象o。如果已经有了值为"abc"的地址,则查找对象o,并返回o的地址。
(3)将str指向对象o的地址。
值得注意的是,一般String类中字符串值都是直接存值的。但像String str = "abc";这种场合下,其字符串值却是保存了一个指向存在栈中数据的引用!
为了更好地说明这个问题,我们可以通过以下的几个代码进行验证。 String str1 = "abc";
String str2 = "abc";
System.out.println(str1==str2); //true
注意,我们这里并不用str1.equals(str2);的方式,因为这将比较两个字符串的值是否相等。==号,根据JDK的说明,只有在两个引用都指向了同一个对象时才返回真值。而我们在这里要看的是,str1与str2是否都指向了同一个对象。
结果说明,JVM创建了两个引用str1和str2,但只创建了一个对象,而且两个引用都指向了这个对象。 我们再来更进一步,将以上代码改成: String str1 = "abc";
String str2 = "abc";
str1 = "bcd";
System.out.println(str1 + "," + str2); //bcd, abc
System.out.println(str1==str2); //false 这就是说,赋值的变化导致了类对象引用的变化,str1指向了另外一个新对象!而str2仍旧指向原来的对象。上例中,当我们将str1的值改为"bcd"时,JVM发现在栈中没有存放该值的地址,便开辟了这个地址,并创建了一个新的对象,其字符串的值指向这个地址。
事实上,String类被设计成为不可改变(immutable)的类。如果你要改变其值,可以,但JVM在运行时根据新值悄悄创建了一个新对象,然后将这个对象的地址返回给原来类的引用。这个创建过程虽说是完全自动进行的,但它毕竟占用了更多的时间。在对时间要求比较敏感的环境中,会带有一定的不良影响。 再修改原来代码: String str1 = "abc";
String str2 = "abc";
str1 = "bcd";
String str3 = str1;
System.out.println(str3); //bcd String str4 = "bcd";
System.out.println(str1 == str4); //true
str3 这个对象的引用直接指向str1所指向的对象(注意,str3并没有创建新对象)。当str1改完其值后,再创建一个String的引用str4,并指向因str1修改值而创建的新的对象。可以发现,这回str4也没有创建新的对象,从而再次实现栈中数据的共享。 我们再接着看以下的代码。 String str1 = new String("abc");
String str2 = "abc";
System.out.println(str1==str2); //false 创建了两个引用。创建了两个对象。两个引用分别指向不同的两个对象。 String str1 = "abc";
String str2 = new String("abc");
System.out.println(str1==str2); //false 创建了两个引用。创建了两个对象。两个引用分别指向不同的两个对象
1.String s1="aa";创建了几个String对象?
『解答』
只创建一个String对象,并且引用s1和它所指的对象本身都存储在栈(stack)中。
-------------------------
对象存储在栈中, 长见识了!
『解答』
创建了一个Sting对象,并且引用s2存储在栈(stack)中,而它所指的对象本身存储在堆(heap)中。
---------------------------
这个回答也不对, 唉!
『解答』
只创建一个String对象,并且s1的引用在(stack)中 但是 "aa"在heap内存里面
『问』
2.String s2=new String("aa");又创建了几个String对象?两句话有什么区别?
『解答』
创建了两个Sting对象,并且s2引用存储在栈(stack)中,s2对象存在heap里面
s2指向了 new 的一个临时String 对象而 这个临时的对象指向了heap里面"aa"的存放地址
String str1 = "abc";
String str2 = "abc";
System.out.println(str1 == str2); //true
说明是地址的比较 在heap上分配"abc"空间之前 查看stack里是否有"abc"的引用 如果有
直接返回(感觉如果这样会造成效率问题)String str1 = "abc";
String str2 = "abcd";
str2 = str2.substring(1,3); //str2 value "abc"
System.out.println(str1 == str2); //false总结 == 始终是比较引用地址是否相等
值的比较只能是equle()方法
只能存在于HEAP
STACK里只能是对象引用的内存地址
内存地址是HEAP区上的起始地址加上偏移量 HEAP里是2进制形式的存放
String str2 = "abc";
System.out.println(str1 == str2); //true只能是String成立如果换Integer则不成立Integer i1 = Integer.valueOf("1");
Integer i2 = Integer.valueOf("1");
System.out.println(i1 == i2); //false 两个不同的内存地址
『问』
1.String s1="aa";创建了几个String对象?
『解答』
只创建一个String对象,并且引用s1和它所指的对象本身都存储在栈(stack)中。
-------------------------
对象存储在栈中, 长见识了!建议你好好看看关于Java是怎样处理在栈和堆中存放数据的。java之所以把primitive的数据存储放在栈中是出于速度考虑。
而其他的Object对象呢全部在堆中存储。
注String 是很奇怪的东西String str1 = "abc";
在栈中分配了引用空间str1,并且在栈中寻找有没有存储值为"abc"的空间,如果有则把该空间的首地址赋值给str1,如果没有则会产生一块新的空间用来存储"abc",并把该空间的首地址赋值给str1.
String str2 = "abc";
同上...
System.out.println(str1 == str2); //true
所以str1和str2存储的地址是相同的,所以打印值应该为true只能是String成立如果换Integer则不成立Integer i1 = Integer.valueOf("1");
它在栈中给引用i1 分配了一个空间,然后在堆中生成了一个对象并且把它的首地址赋值给i1,所以我们就可以用栈中的引用i1来操作堆中对应的对象了。
Integer i2 = Integer.valueOf("1");
它在栈中给引用i2 分配了一个空间,然后在堆中生成了一个对象并且把它的首地址赋值给i2,所以我们就可以用栈中的引用i2来操作堆中对应的对象了。System.out.println(i1 == i2); //false 两个不同的内存地址
因为引用i1和i2所指不同的对象,所以他们的值也不相同。
注:栈中的数据是可以共享的,而堆中的数据是不可以共享的。int a = 3;
int b = 3;
分析:
其实在栈中存储3这个值的这个内存块只有一个。a和b 是共享的。a和b中实际是存储3这个内存块的地址。两个引用存储的是同一个地址,无论如何a始终等于b。
因为OBJECT 的REFERNCE 也在STACK里面
如果每次产生一个东西都需要去STACK里面查询一次 效率上真的不怕吗
怀疑中 ~~~在Java Doc有这段对于Stack存储区的描述
stack storage object references--java objects themselves are not placed on the stackString is object and still a primitive types
so if you use // new String("aa"); is a String Object in heap
if you use //String s1="aa"; "aa" is in stack not in heap
不过这有点矛盾 后者至少 会产生一个对象
前者是产生了两个对象郁闷ING
String str2 = "abc"; 肯定STRING OBJECT在HEAP里面 那建立了对象为什么会出现在STACK 而不是HEAP
//String is object
Stack 里面的东西是共享的
String s1 = "aa";
产生了一个 STRING OBJECT 在HEAP里面 他的引用在STACK里面 "AA" 内容却在STACK里面
S1 在STACK里的引用指向HEAP里面的STRING对象 HEAP里的对象把内容放在了STACK里
而其他的Object对象呢全部在堆中存储。
--------------------
我只是说对象绝对不会存储在栈中, 好像没有说其他的吧.