日期:2014-05-20  浏览次数:20725 次

请教自己在编程中的一个疑问:我一直不明白一个问题...
我一直不明白一个问题(我以这个例子来说吧,见绿色方框标注):String uname,我们看到本质上uname是一个对象,我们也看到string uname=" ",它后面可以跟“值”,我有个疑问就来了,是对象后面都可以直接跟“值”吗?我印象中好象并不是这样,对象后面总是跟着“.”,不知道为什么,这让我联想到了光的波粒二象限,老师告诉我uname是个对象,可是给我的感觉是它又能作为变量一样去使用,大家能不能和我具体地讲一讲这个问题啊?

http://imm.io/btyX

------解决方案--------------------
这个问题就要拿内存来说说了:
首先你要清楚一点就是:String是引用数据类型与其他基本数据类型不一样比如:int a=0;这只是在栈中生成了一个变量a这个变量存放了0这个值的地址;而对String,我们经常看到的有这两种方式:String str ="abc";和String str=new String ("abc");
那就分别来说说:
String str="abc";这样写的时候java虚拟机首先会在字符串常量池中查找是否已经有了"abc"这个字符串如果有了,直接把它赋给str,如果没有则在字符串常量池中新建一个字符串"abc"并将它赋给str,字符串常量池是属于栈中的一个部分;
而String str=new String ("abc");这样写java虚拟机就在堆(堆是用来存放对象的)中new了一个对象,在此并不会去检查队中是否已经有了"abc"这个对象,因为你每次new 出来的都是不同的对象,就算他的字面值相同,但他们的地址是不同的,就是不同的对象,搞清楚这个过程再来看下面:
我们还经常会这样做 String str="abc";中间写一些代码后又再这样做str=str+"def";这些操作都是在栈中进行的,看上去我们是在原来的"abc"后面添加了"def"而实际上,新的str是指向了另外一个内存空间这个空间存放了"abcdef",而原来的"abc"依然在哪里(没有引用了的对象会在某个时间被垃圾回收器回收)
看了这些再来看看你上面的问题:首先java中一切都是对象,String没有例外,我们用一个类名来声明一个变量,那么这个变量就是这种类型的一个实例,它是一个对象,所以你上面说的没有疑问uname是一个对象,那为什么能这样做呢uname="ajfbak"?;这就算String的特殊,它能同时进行堆和栈的操作,所以我们在编程中还经常这样写 String unmae="sdf";if(uname.equals("sdf")||uname==null){.......}这就是String类的对象同时进行堆、栈操作的优越