您的位置:首页 > 编程语言 > Java开发

Java编程思想学习心得(四)赋值操作符的陷阱

2015-12-08 17:09 344 查看
在任何一门语言中,操作符都是必备的,在Java中也不例外。在操作符中,我们最先接触的就是赋值操作符,即“=”。这个操作符的含义是将“=”右边的赋给左边,如下面的代码所示:

int a = 1 ;
这种是基本类型的赋值,就是说将“1”这个值直接存储在变量“a”里,并存储在堆栈里。

还有像下面这种形式:

Object obj = new Object() ;
这种是Java中非基本类型的赋值,创建了一个obj引用,用new创建了一个Object对象,并将obj引用指向这个对象。

在Java中最基本的就是这两种形式,但是这两种在使用赋值操作符的时候,存在一些差异,对于基本类型,像下面这样的代码:

int a = 1 ;
int b = 2 ;
a = b ;
b = 3 ;
如果此时输出a和b,那么a的值应该是2,b的值应该是3。这应该是显而易见的,这种基本类型变量直接存储值,所以说“a = b ;”这句相当于直接把b的值2存储到变量a中,所以变量a中存储的值就是2,下面再执行“b = 3 ;”就是把值3存储到变量b中,那么变量b的值就是3。变量a的改变和变量b毫不相关。

对于Java中的非基本类型,情况就有了一些差异,像下面这样的代码:

public class User {

String name;

public static void main(String[] args) {
User one = new User();
one.name = "张三";
User two = new User();
two.name = "李四";
System.out.println("one name=" + one.name + "two name=" + two.name);
one = two;
System.out.println("one name=" + one.name + "two name=" + two.name);
two.name = "王五";
System.out.println("one name=" + one.name + "two name=" + two.name);
}
}
可以看到,我们在代码中输出了三次,我们看一下输出的结果:

one name=张三two name=李四
one name=李四two name=李四
one name=王五two name=王五
可以看出,输出的结果和我们前面说的基本类型的情况出现了差异,我们根据一步一步来分析。

首先,我们创建了两个User类型的变量one和two,其中one中的name为“张三”,two中的name为“李四”,再看我们的第一次输出,是没有问题的。接着我们执行了“one = two ;”,将two赋给了one,再看第二次输出,此时已经将two赋给了one,所以one中的name应该和two中的一样,所以都输出“李四”也是没有问题的。最后,执行“two.name = "王五" ;”,我们来看第三次的输出,one和two都输出了“王五”,这样的结果好像超出了我们的预期,根据前面基本类型的概念,此时“应有”的输出应该是one输出“李四”,two输出“王五”,可是为什么one和two都输出了“王五”呢?

这是因为,Java中非基本类型的赋值操作,其实是对引用做的操作。根据非基本类型的特点我们知道,像“Object obj = new Object() ;”这种语句,真实的含义是创建了一个名为obj的变量存放在堆栈上,里面存放的是指向一个Object对象的引用,这个Object对象通过new创建出来,存储在堆上。那么像“one = two ;”这种赋值语句实际上的含义是将two的引用赋给one,那么此时one和two都指向了two所指向的对象,所以输出的时候,one和two所输出的内容是一样的,并且,改动一个,另一个也会跟着动,因为这两个变量的引用指向的是同一个对象。

ps:String类的情况有些特殊,之后再讲。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: