该帖已经被评为良好帖
|
|
---|---|
作者 | 正文 |
发表时间:2011-08-17
fellatioyzx 写道 我都答对了
关于最后一题的话,由于java方法传值是值传递,所以方法里面的ab虽然和方法外的ab指向的对象一样,但是这两个引用在栈中的位置不一样。 过程大概是首先在栈中复制引用a为a',b为b',并令a'指向a所指的在堆中的StringBuffer对象,b'指向b所指的在堆中的StringBuffer对象。 因此方法中的b=a只是起到了b'=a'的作用,并没有影响方法外b的指向。 java只在基础类型是值传递吧。复杂类型都是引用传递 |
|
返回顶楼 | |
发表时间:2011-08-17
neverforget 写道 投你个良好 请帮忙细讲下
double j = 1 / 4 + 3 / 4; j==0 是怎么个隐形 精度转换 两个int做除法运算,java认为结果也应当是int,所以舍精度,就为0 |
|
返回顶楼 | |
发表时间:2011-08-17
tom&jerry 写道 由于1/4和3/4发生隐性类型转换,精度损失,不会生成0.25和0.75,所以有分号的数都为0。
个人认为java对于除数和被除数同时为int时其运算法则和C语言相同,并非是精度损失,而是相当于运算符重载。 只不过是两个整型的计算,其结果还是整型而已。 |
|
返回顶楼 | |
发表时间:2011-08-17
liwenjie 写道 那么(a == (x + y))为什么是false呢?这点暂点有点不大清楚。初步认为是x+y是引用相加,不能放入常量池。
因为x+y不是编译是确定值而是运行时确定值 七:对象引用 java是按值传递,对象类型的话,分为栈上的引用和堆上的对象,栈上的引用被复制一份,如果操作堆上的对象则对象改变,但是如果操作引用则不改变 这个分析的不错! |
|
返回顶楼 | |
发表时间:2011-08-18
一直用equals 比较字符串是否一样, 还真没用过 == 比较 。
|
|
返回顶楼 | |
发表时间:2011-08-23
akunamotata 写道 关于第二题,我画了个图,有错请务必指出,免得误人子弟。
我觉得有点不对 |
|
返回顶楼 | |
发表时间:2011-08-24
4.那么(a == (x + y))为什么是false呢?这点暂点有点不大清楚。初步认为是x+y是引用相加,不能放入常量池
String是不可变数据类型,在X+Y时String会进行重新New一个String。 |
|
返回顶楼 | |
发表时间:2011-08-24
JacobsChen 写道 fellatioyzx 写道 我都答对了
关于最后一题的话,由于java方法传值是值传递,所以方法里面的ab虽然和方法外的ab指向的对象一样,但是这两个引用在栈中的位置不一样。 过程大概是首先在栈中复制引用a为a',b为b',并令a'指向a所指的在堆中的StringBuffer对象,b'指向b所指的在堆中的StringBuffer对象。 因此方法中的b=a只是起到了b'=a'的作用,并没有影响方法外b的指向。 java只在基础类型是值传递吧。复杂类型都是引用传递 public class TestRef { /** * @param args */ public static void main(String[] args) { StringBuffer a= new StringBuffer("a"); StringBuffer b=new StringBuffer("b"); append(a, b);//传递a 和 b对象的引用 System.out.println("main方法内调用append方法后的值:"+a+" "+b); b=a; System.out.println("main方法执行b=a后:"+a+" "+b); User u= new User(); System.out.println("u对象的地址:"+u); System.out.println("u对象name old值:"+u.name); charge(u); System.out.println("u对象name new 值:"+u.name); ///////////////// User ua=new User(); User ub=new User(); System.out.println("变化结束前:"); System.out.println("ua对象的地址:"+ua); System.out.println("ub对象的地址: "+ub); charge2(ua, ub); System.out.println("变化结束后:"); System.out.println("ua对象的name值:"+ua.name); System.out.println("ub对象的name值: "+ub.name); } private static void charge(User u) { System.out.println("u对象的地址:"+u); u.name="b";//改变u对象的name属性值 } //该方法操作的是main ua ub的副本, //对对象name属性的内容操作会返回到对象上,改变的内容是堆上User对象的内容 //但是在此方法里面 改变ua ub的引用内容 是不会反应到main方法上 private static void charge2(User ua,User ub) { System.out.println("charge2方法一系列变化开始...."); ua.name="iteye";//改变ua对象上的name属性值为iteye System.out.println("ua对象的地址:"+ua); System.out.println("ub对象的地址: "+ub); ua=new User(); ua.name="c";//改变ua对象上的name属性值为c ub=ua; System.out.println("charge2方法一系列变化结束!"); } /** * * @param a 传递是a的引用 * @param b 传递是b的引用 */ static void append(StringBuffer a,StringBuffer b){ a.append(b);//改变的是堆上对象a的内容 b=a;//传递是b的引用 但是此时改变了b引用对象[存在于堆上], //方法调用会产生一个虚拟机栈,并且压入栈顶, 此时a 和b 在栈里面只是一个副本引用 //但是副本的引用分别指向堆上的a b,此时改变的是b的引用对象 指向了a,但是对于原来的b不会产生作用 //但是下面我们指行这个 还是能再本方法中看到效果,但是在main方法中就看不到效果了,要看到话 需要重新 b=a; System.out.println("append方法内的执行结果"+a+"\t"+b); } } 输出结果: append方法内的执行结果ab ab main方法内调用append方法后的值:ab b main方法执行b=a后:ab ab u对象的地址:org.hhb.trap.User@c17164 u对象name old值:a u对象的地址:org.hhb.trap.User@c17164 u对象name new 值:b 变化结束前: ua对象的地址:org.hhb.trap.User@1fb8ee3 ub对象的地址: org.hhb.trap.User@61de33 charge2方法一系列变化开始.... ua对象的地址:org.hhb.trap.User@1fb8ee3 ub对象的地址: org.hhb.trap.User@61de33 charge2方法一系列变化结束! 变化结束后: ua对象的name值:iteye ub对象的name值: a |
|
返回顶楼 | |
发表时间:2011-08-25
mark 感觉很有用
|
|
返回顶楼 | |
发表时间:2011-08-31
最后一道lz的分析是正确的。
|
|
返回顶楼 | |