这是我个人的csdn 的博客中所描述的你的内容,咱们可以分享分享。文章标题为《Java 值传递和引用传递(语句拆解理解) 》,我前几天写的第一篇博客,下面把我的博客内容贴出来吧。
Java值传递和引用传递让很多比较纠结,其实在Java中只存在值传递,此时又有人会提出疑问,哪为什么在Java中将一个对象作为方法的参数的时候却可以改变这个对象的属性呢?
这个问题呢,个人感觉还是基本知识的理解不够透彻的原因,下面是我的一些拙见,如果有什么问题呢,还请大家提出来,share and change!
个人觉得有的语句看起来复杂,只要一步一步拆解来看,还是很简单的
第一,咱们先看看貌似和这个问题联系不大的一个基本知识.
一条最基本的java面向对象的语句,
ClassA a = new ClassA();
大家应该知道,这是两个语句的一个简写,即
(1) ClassA a;
(2) a = new ClassA();
这两句话的基本含义大家应该清楚吧,
最基本的理解是这样的,创建了一个ClassA的对象,并且用a来指向这个对象
再细致一点的话,可以这么说,在内存中开辟了一个空间,这个空间用来放一个新创建的ClassA对象.但是这个对象我怎么操作呢,我得知道这个对象放在哪个地方吧,所以这时就用一个标记把他记下来,方便操作,专业一点的说法呢,我得知道这个对象的内存地址,然后才能对他进行数据的操作.
这时可以看到,第1句话的作用其实就是创建了一个内存地址的值的标记,当让这这是简单的理解方式.
第二,我们再看看类的方法的一些细节知识,比如有下面的一个例子,ClassA的对象作为参数传递给另外一个类ClassB(这其实是错误的说法,个人感觉严格的说法是引用到了另外的一个类的对象)
class ClassB{
public void change(ClassA a){
a.setNo(10);
}
}
在类ClassB中呢,我们用到了一个ClassA的引用a,为什么说这个不是拿过来a这个对象在操作呢?
其实这个还是语句拆解的问题,整体代码,我们浏览一下
public class Test {
public static void main(String[] args) {
// TODO Auto-generated method stub
ClassA a;
a = new ClassA();//为了便于理解,故意拆分
a.setNo(5);
ClassB b;
b = new ClassB();//为了便于理解,故意拆分
b.change(a);
}
}
/**
*仅作为简单的被引用的类
*/
class ClassA{
private int no;
public int getNo() {
return no;
}
public void setNo(int no) {
this.no = no;
}
}
/**
* 调用其他的类做演示
*/
class ClassB{
public void change(ClassA c){
c.setNo(10);
}
}
在上面的这段代码上,我们要看的代码的是主函数的最后一句
b.change(a);
为什么这句话之后,a的no属性就会变成10,而不再是5呢
是这样的,我们也可以拆解这个过程
这个过程可以这样理解的
a呢把自己的引用传给了b的方法的参数c
就是这个意思,
ClassA c = a;
所以呢,c指向的是和a相同的一个内存地址,假如说a指向的是00FF,那么c指向的也是00FF.在传递过程中传递的是这个.
理解了这个道理后,我们便可以理解下面的问题了,假如在ClassB中的change方法中,我改变了参数c指向的地址,我在change方法内部创建了一个新的ClassA对象d,那么a的内容会随之变化吗,大家想想?代码如下
/**
* 调用其他的类做演示
*/
class ClassB{
public void change(ClassA c){
c= new ClassA();
c.setNo(20);
}
}
这个便可以理解了,当然是不会的,因为c本来指向的是a所代表的地址00FF,现在我们在操作的是c,把c指向了一个新的ClassA对象,这个内存地址假如说是01FF;那么c所对应的内容改变当然不影响a的内容.
理解了这个,便知道了网上的一种说法,"对象作为参数传递到方法中,其实就是拷贝了一个引用的副本".
说完了这个呢,可能会有人有其他的疑问:
(1)为什么我用基本类型传递,然后在方法中做改变,结果他本身的值没有发生变化呢?
这个我们再说道说道
因为java的基本数据类型和这些类的类型有区别,因为基本类型占用的空间是已知的,并且是简单类型,所以在传递的过程中,直接就把这个值给复制了一份,再进行操作,所以您老人家操作的是复制的那份数据,而不是原来的那个数据
(2) 为什么数组作为参数传递时,改变数组的内容,就有效果呢?大家可以翻翻api文档哈,文档中已经说了,不管是基本类型的数组,还是类的数组,他们的基类是Object,所以呢,他是遵守我们最开始说的,对应引用的传递的规则. |