论坛首页 Java企业应用论坛

Java容易搞错的知识点-觉得基础扎实的来看

浏览 61937 次
该帖已经被评为良好帖
作者 正文
   发表时间:2011-08-17  
fellatioyzx 写道
我都答对了

关于最后一题的话,由于java方法传值是值传递,所以方法里面的ab虽然和方法外的ab指向的对象一样,但是这两个引用在栈中的位置不一样。

过程大概是首先在栈中复制引用a为a',b为b',并令a'指向a所指的在堆中的StringBuffer对象,b'指向b所指的在堆中的StringBuffer对象。
因此方法中的b=a只是起到了b'=a'的作用,并没有影响方法外b的指向。

java只在基础类型是值传递吧。复杂类型都是引用传递
0 请登录后投票
   发表时间:2011-08-17  
neverforget 写道
投你个良好 请帮忙细讲下
double j = 1 / 4 + 3 / 4;

j==0 是怎么个隐形 精度转换

两个int做除法运算,java认为结果也应当是int,所以舍精度,就为0
1 请登录后投票
   发表时间:2011-08-17  
tom&jerry 写道
由于1/4和3/4发生隐性类型转换,精度损失,不会生成0.25和0.75,所以有分号的数都为0。

个人认为java对于除数和被除数同时为int时其运算法则和C语言相同,并非是精度损失,而是相当于运算符重载。



只不过是两个整型的计算,其结果还是整型而已。
0 请登录后投票
   发表时间:2011-08-17  
liwenjie 写道
那么(a == (x + y))为什么是false呢?这点暂点有点不大清楚。初步认为是x+y是引用相加,不能放入常量池。

因为x+y不是编译是确定值而是运行时确定值

七:对象引用
java是按值传递,对象类型的话,分为栈上的引用和堆上的对象,栈上的引用被复制一份,如果操作堆上的对象则对象改变,但是如果操作引用则不改变


这个分析的不错!
0 请登录后投票
   发表时间:2011-08-18  
一直用equals 比较字符串是否一样, 还真没用过 == 比较 。
0 请登录后投票
   发表时间:2011-08-23  
akunamotata 写道
关于第二题,我画了个图,有错请务必指出,免得误人子弟。


我觉得有点不对
0 请登录后投票
   发表时间:2011-08-24  
4.那么(a == (x + y))为什么是false呢?这点暂点有点不大清楚。初步认为是x+y是引用相加,不能放入常量池
String是不可变数据类型,在X+Y时String会进行重新New一个String。
0 请登录后投票
   发表时间: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

0 请登录后投票
   发表时间:2011-08-25  
mark 感觉很有用
0 请登录后投票
   发表时间:2011-08-31  
最后一道lz的分析是正确的。
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics