1.String str=new String("test");//创建了一个对象,一个引用.对象new String("test")呆在堆里,那个引用str又该呆在那里?
2.String str2="test2";//是不是一个对象也不会产生?"test2"是字符串常量呆在栈中,str2是引用,没有对象产生?
3.晕头转向?
2.String str2="test2";//是不是一个对象也不会产生?"test2"是字符串常量呆在栈中,str2是引用,没有对象产生?
3.晕头转向?
public static void main(String[] args) {
String s1=new String("test");//从结果可以看出这里产生对象
String s2=new String("test");//这里也产生了
String s3="test";//这里没有
String s4="test";//这里也没有它和S3共同指向一个字符串.
System.out.println(s1==s2);//false
System.out.println(s2==s3);//false
System.out.println(s3==s4);//true}
}以上分析不知道对否,晕...........
-------------------------
你跟我差不多sb,你就别回了,等高手解答吧.
你的s1 s2 s3 s4就产生了一个对象,四个引用。
用equals比较一下就知道了,返回的都是true说明他们四个都指向同一个对象。
你的s1 s2 s3 s4就产生了一个对象,四个引用。
用equals比较一下就知道了,返回的都是true说明他们四个都指向同一个对象。
---------------------------------------
String s1=new String("test");
String s2=new String("test");????s1和s2会是同一个对象?看来你比我还sb(我不是骂人,我习惯于这样说)
String s3="test";
-----------------------------
引用s2,s3会指向同一个"test"?
我认为s2指向的是堆中的一个String型类的对象,该对象内含"test"这样的一个字符串.
s3会指向栈中的"test"字符串常量.tnnd,也不知道我的理解差多少.
1):在JVM中有一个字符串池,如果(
String s1=new String("aaa");
在字符串池中有一个空间。
而String s2=s1;
在字符串池中有相同的内容所以JVM就在池中找。不会产生新的对象。
但(String s2=new String("aaa");)就产生了新的对象。
)
仅供参考。
1)在堆里
2)产生了一个对象,一个引用。String str2="test2";只是SUN公司的天才们将'='运算符重载而以。同String str2=new String("test2");
仅供参考
堆。一种常规用途的内存池(也在RAM区域),其中保存了Java对象。和堆栈不同,“内存堆”或“堆”(Heap)最吸引人的地方在于编译器不必知道要从堆里分配多少存储空间,也不必知道存储的数据要在堆里停留多长的时间。
String s2=new String("test");
String s3="test";
String s4="test";
应该是创建3个对象,两个new String("test")在堆里,一个"test"在栈内
类似于String s3="test"这种,先到栈中去寻找"test",有就创建个引用,没有先在栈中创建一个"test"对象,在创建引用
栈中一般只存放基本变量,但java中String是一个比较特殊的对象
String s2=new String("test");
不就是用new在堆中分配内存吗
String s4="test";
也就是C++中的操作符重载吗?
在部内也是先在堆中分配内存,然后把字符一个一个拷到刚分配的内存中来不懂的快学C++去...
str = new String("test");//在堆中分配一个对象,然后把分配的内存首地址赋给刚才的str
超出str范围后,str就被弹出。如果str所指的对象没有被引用了,就可以标志为“垃圾”了没学过JAVA,虽然说说
请不要骂我SB,不然切你小JJ
2.没有新对象产生,也没有新引用产生
现在分析大家讨论的这一点:
String s1=new String("test");//这里分别在堆中分配了一个新的对象和在栈中分配了一个新的引用
String s2=new String("test");//这里是在堆中的s1指向的那个对象和在栈中分配了一个新的引用
因此这里s1!=s2,但s1.equals(s2)==true
String s3="test";//这里是在堆中的s1指向的那个对象和在栈中分配了一个新的引用,这里s2!=s3,但s2.equlas(s3)==true
String s4="test";//这里是在堆中的s1指向的那个对象和在栈中的s3.相当于s4=s3引用赋值
2、这种发法创建string对象和第一种方法一样,"str2"是对象的引用,所以在栈里。"test2"理所当然在堆里。
3、建议看一看 java编程思想
public static void main(String[] args) {
String s1=new String("test");//从结果可以看出这里产生对象
String s2=new String("test");//这里也产生了
String s3="test";//这里没有
String s4="test";//这里也没有它和S3共同指向一个字符串.
System.out.println(s1==s2);//false
System.out.println(s2==s3);//false
System.out.println(s3==s4);//true
}
}
------------------------------------------
把三条输出语句都换成这样的形式:System.out.println(s1equals(s2));//这才是比较值的方法。结合上面的输出就知道答案了
String str1 = "test";
String str3 = new String("test");
System.out.println(str1 == str3); //输出false
str1 = str3.substring(0,2);
str3 = str3.substring(0,2);
System.out.println(str1 == str3);//输出false
}
可见通过new操作符产生的String是为每个新产生的字符串分派一个对象,以后居于这个String操作所产生的String也会产生一个新的对象。public static void main(String[] args){
String str1 = "test";
String str2 = "test";
System.out.println(str1 == str2);//true
str1 = str2.substring(0,2);
str2 = str1.substring(0,2);
System.out.println(str1 == str2);//true
}
没有通过new 操作符号产生的String应该是在一个池里,每当一个操作结果和池里的某个值相等就做为引用,否则就产生一个新的String加入到池我也不知道对不对,不要骂哈,我很少来。
看了大家的帖子,虽然都有说法,但有个共同的问题? 1.简单数据类型,引用类型在内存中究竟是怎么存放的,大家不清楚!
2.用new 会创建一个对象,然,我们对对象操作,实际是对对象的引用的操作,那么这个对象和 他的引用是怎么存放的呢?
如果比较清楚的, 回答这两个问题,大家都清楚了!
String s2=new String("test");
上面两个创建了两个指向 "new String("test")"对象的引用 s1 ,和s2; 在内存中怎么放的看上面.而这两个 因为String是引用型的, 所它们只是创建了两个引用,没有对象,这样是允许的!
String s3;
String s4;这两个就是java语言的特性了,"在创建引用的同时便进行初始化",即,字符串可以用带引号的文本初始化!
String s5="test";
String s6="test";清楚否???
我来作也详细点的:String str ;
这样声明str它只是一个对象的reference,不会产生实际的对象。如果没有初始化str,编译时便会发生错误。 String str1=new String("test");
String str2 = "test";
str1是一个新的对象。new关键字的意思就是创建某个新的对象。而str2是一个对象的引用。它们的内容相同,但内存地址是不一样的。 java中对象的引用存在Stack(栈)中,而对象由Heap(堆)分配空间。 引用==变量? 不一定
public class TestString {
public static void main(String[] args) {
String s1 = "test";
String s2 = new String("test");
if (s1 == s2)
System.out.println("s1 == s2");
else
System.out.println("s1 != s2");
if (s1.equals(s2))
System.out.println("s1 equals s2");
else System.out.println("s1 not equals s2");
}
} 我们将 s2 用 new 操作符创建程序输出:s1 != s2 s1 equals s2.
java代码: s2 = s2.intern(); 在你加上这句话后,上面的程序输入:s1 == s2 s1 equals s2 而String a = "test" ; String b = "test" ; a == b 会返回true; 这里a="test"时创建一个在栈中的reference, b=test时jvm发现栈中已存在名为"test"的字符串,直接引用。结论:String 是个对象,要对比两个不同的String对象的值是否相同明显的要用到 equals() 这个方法. 而== 比较的是内存地址的值。 private final String a = "test",
这个a属于常量,存放在常量存储空间(CS)中。 总结
1.引用是一种数据类型,保存了对象在内存中的地址,这种类型即不是我们平时所说的简单数据类型也不是类实例(对象);
访问对象的时候,我们不会直接是访问对象在内存中的数据,而是通过引用去访问.Java 中简单类型没有引用。
2.JAVA所有的对象都是存放在堆中的!你获取的"对象"仅仅只是对象的引用而已
3.==比较的是内存地址.而equals比较的是内存地址对应的值,即内容。
4.String是比较特殊的对象,特殊在
String a = new String("test") -此时你是在堆中实例化了一个字符串对象
String b = "test"-此时JVM会先去堆中寻找这样的对象;如果有就返回此对象的引用;如果没有就重新实例化一个这样的对象!基于这样的一个过程所以JAVA要求String不可以更改值的。
5.这里有一份详细的参考资料:
关于Java栈与堆的思考 http://www.javafan.net/article/20051123115654293.html
6.建议你看看<<深入浅出java虚拟机>>一书。
你的s1 s2 s3 s4就产生了一个对象,四个引用。
用equals比较一下就知道了,返回的都是true说明他们四个都指向同一个对象。
---------------------------------------
String s1=new String("test");
String s2=new String("test");????s1和s2会是同一个对象?看来你比我还sb(我不是骂人,我习惯于这样说)
-----------------------
你试过了么?看样子你是够sb呢,你不知道实践出真知么?
曾经在VC 6.0环境下试过,的确是这样子,现在vc2005懒得试不同意你说话的方式
http://www.bc-cn.net/Article/kfyy/java/jszl/200601/3072.html
仔细研究一下,共同进步。
String str2=new String("abc");
System.out.println(str1==str2)
//false
解释:
上面首先在栈内存中定义了两个变量,然后又用new 在堆内存中生成了两个对象,并且把他们在堆内存中的首地址赋值给栈内存中的对应的变量。由于这两个对象的地址一定是不相等的,所以打印结果应该为“false”
//////////////////////////////////
String str1="a";
String str2="a";
System.out.println(str1==str2);
//true
解释:
上面首先在栈内存中定义了两个变量,并且把他们的值都赋为“a”,所以是相等的
String str1=new String("abc");
String str2="abc";
搞不清楚,对于第二个式子是否创建了对象不太清楚;看了全部回帖,同意diy8187(雞狗豬驢) 的分析;