|
| 1 | +##Java是按值传递还是按引用传递 |
| 2 | + |
| 3 | +###概念定义 |
| 4 | +在开始之前,我们先理解按值传递、按引用传递的概念。 |
| 5 | +1、什么是值传递? |
| 6 | +指的是在方法调用时,传递的参数是按值的拷贝传递。按值传递重要特点:传递的是值的拷贝,也就是说传递后就互不相关了,每个值都对应到一个地址空间 |
| 7 | +2、什么是引用传递 |
| 8 | +指的是在方法调用时,传递的参数是按引用进行传递,其实传递的引用的地址,也就是变量所对应的内存空间的地址。传递的是值的引用,也就是说传递前和传递后都指向同一个引用(也就是同一个内存空间)。 |
| 9 | + |
| 10 | +###结论 |
| 11 | +明确地说,java都是按值传递的!java的世界里,都是按值传递。其实按值、按引用都只是个概念,关键是我们如何去理解java传参的本质。 |
| 12 | + |
| 13 | +###例子 |
| 14 | +下面就结合一个例子来说 |
| 15 | +有些情况下,所参数参数的值,是个"引用",这一点容易让人产生困惑。 |
| 16 | + |
| 17 | +请看下面的例子 |
| 18 | +首先有如下代码 |
| 19 | +[java] view plaincopyprint? |
| 20 | +Dog myDog = new Dog("Rover"); |
| 21 | +foo(myDog); |
| 22 | +这时,你传给了foo函数一个参数,这个参数值,是个引用,也就是Rover这只dog的内存地址(这只是粗略的说明,因为在java中,这个地址并非是真正的地址) |
| 23 | +假设这时候Rover的地址是42,那么,我们就是传了42这个地址给foo方法 |
| 24 | +```java |
| 25 | +public void foo(Dog someDog) { |
| 26 | + someDog.setName("Max"); // AAA |
| 27 | + someDog = new Dog("Fifi"); // BBB |
| 28 | + someDog.setName("Rowlf"); // CCC |
| 29 | +} |
| 30 | +``` |
| 31 | +让我们逐步解析foo方法 |
| 32 | +1. 参数 someDog的值是一个地址(42) |
| 33 | +2. 在AAA这一行: |
| 34 | +someDog,也就是函数外声明的myDog,name从Rover被改成了Max |
| 35 | +3. 在BBB这一行: |
| 36 | +这就是关键的地方了,又new了一只dog,new 意味着又在新的地址空间放上了一只Dog,我们假设其地址是74。这时,someDog的值,会从42变成了74 |
| 37 | +4. 在CCC这一行: |
| 38 | +这时候的修改,是对内存地址为74的那只狗的修改,而非原先的42 |
| 39 | + |
| 40 | +从这个例子,我们可以看到,foo方法的参数someDog,它是一个值,而非引用。如果它是引用,那么在foo方法内部的修改(包括BBB、CCC这两行),都应该会对42地址空间的dog产生影响,也就是方法外的参数,mydog也会指向新的地址空间。 |
| 41 | + |
| 42 | +###重要提醒 |
| 43 | +**再总结下Java初学者容易犯错的地方:** |
| 44 | +假如你想像例子一样,传递一个对象到一个方法中,并由该方法修改对象。 |
| 45 | +- 可以成功修改a |
| 46 | +```java |
| 47 | +Object a = new Object(); |
| 48 | +foo(a){ |
| 49 | +a = new Object(); |
| 50 | +a.setXXX("XX"); |
| 51 | +} |
| 52 | +return a;//a实际未被修改 |
| 53 | +``` |
| 54 | + |
| 55 | +- 不可以成功修改a |
| 56 | +```java |
| 57 | +Object a = new Object(); |
| 58 | +foo(a){ |
| 59 | +a.setXXX("XX"); |
| 60 | +} |
| 61 | +return a;//此时的a已经是修改后的值 |
| 62 | +``` |
| 63 | + |
| 64 | + |
| 65 | +要切记,这个Object一定要在调用方法前,就初始化好(new一个),然后再作为参数传进去,并且在方法中不能再初始化这个参数。这样,在方法中对该参数的修改,才会有效地修改到a这个变量 |
| 66 | + |
| 67 | + |
| 68 | +stackoverflow链接 |
| 69 | +http://stackoverflow.com/questions/40480/is-java-pass-by-reference-or-pass-by-value |
0 commit comments