《Java编程思想》读后感:赋值操作符

赋值操作符在许多编程语言中都经常出现,之前我对其的理解都是将右边的值复制给左边,当然,左边不能为常数,比如可以说 a = 4 而不能说 4 = a。最近在读《Java编程思想》的操作符这一章时才发现,在某些情况下“=”的使用结果会与我们预期相差很远(如果对它的理解还是跟之前一样简单的话)。

产生这种偏差的原因正是面向对象编程的特点之一:Java中对一个对象操作往往操作的是对象的引用,所以之前的理解将一个对象赋值给另一个对象实际变成了将引用从一个地方复制到另一个地方,比如a = b,则ab这两个引用指向的对象都变成原来b指向的对象。而对基本类型进行操作的话则是将b的内容复制到a,且b的内容不会受任何影响。简单例子如下:

package test;

class Test{
	int i;
	public Test(int i) {
		super();
		this.i = i;
	}
	
}
public class Blog {
	public static void main(String[] args) {
		Test t1 = new Test(5);
		Test t2 = new Test(11);
		System.out.println("t1:"+t1.i+" t2:"+t2.i);
		t1 = t2;
		System.out.println("t1:"+t1.i+" t2:"+t2.i);
		t1.i = 20;
		System.out.println("t1:"+t1.i+" t2:"+t2.i);
	}

}

运行结果如下:

t1:5 t2:11
           t1:11 t2:11
           t1:20 t2:20

我们可以发现当执行t1=t2这个操作后,修改t1的同时也会改变t2!这是因为这里赋值操作符使t1t2两个引用指向同一个对象。有人可能会奇怪:就算指向同一个对象,两个引用还是独立的啊,为什么改变一个的指向就把两个都改变了?《Java编程思想》给出的解释是:原本t1包含的指向5的引用在对t1赋值的时候被覆盖,也就是丢失了;而那个不再被引用的对象会有“垃圾回收器”自动清理。

这种现象称为“别名现象”,是Java操作对象的一直基本方式。为了避免这个问题,可以用直接操作字段的方式:

t1.i = t2.i;

这样就可以保持对象的独立,但《Java编程思想》也提到:直接操作对象中的域容易导致混乱,并且违背了良好的面向对象程序设计的原则。对这一点我现在还没有更具体的理解。

另外,将一个对象传递给方法时也会产生别名问题:

package test;

class Test{
	int i;
	public Test(int i) {
		super();
		this.i = i;
	}
	
}
public class Blog {
	public static void main(String[] args) {
		Test t1 = new Test(5);
		System.out.println("t1:"+t1.i);
		f(t1);
		System.out.println("t1:"+t1.i);

	}
	public static void f(Test y){
		y.i = 7;
	}
}

看似方法f只是在其作用域里产生了Test类的一个对象,但实际上传递的参数是引用,所以方法f实际影响了f()以外的对象。

总之在编程中这个现象算是个值得注意的陷阱。

发布了5 篇原创文章 · 获赞 0 · 访问量 149

猜你喜欢

转载自blog.csdn.net/dollyandkalin/article/details/82665028
今日推荐