Java中的传递参数分为两种:一种是基本类型参数的传递,另外一种就是对象的传递.
对于基本类型的传递,我们先看一个例子:
package com.king.chat.test;
public class ParamTest {
public static void changeInt(int i){
i = i+1 ;
System.out.println(i);
}
public static void main(String[] argc) {
int k= 10 ;
System.out.println(k);
changeInt(k);
System.out.println(k);
}
}
这个例子的输出结果是 10
11
10
通过结果显而易见在调用函数changeInt()的时候没有对传入的参数进行任何的改变,您可以试一试其他的基本类型,结果也是一样的.
所以,在java中,对基本类型参数的传递采取的是开辟一块新的内存(作用域就是这个方法),然后把原来的变量的值赋值给该内存. 所以我们在changeInt()函数中的更改无非是对新的内存上的数据的更改。(我提倡的是java中的参数传递都是传值操作,这里传的是内存中的数据)
(可以举个例子: 有一对双胞胎兄弟 ,有一天需要哥哥去当兵,但是因为某个原因,真正被送走的是卵生弟弟,而弟弟在当兵过程中所经历的并没有发生在哥哥身上)。
基本类型实参和形参之间的关系:
Id Addr Value state
K 0x00001 10 1
I 0x00005 10 2
这里我们处理的只是Value 。
对于对象的传递,我认为传的也是值,只是这个值是一个引用的值(类似C语言中的传值和传地址,其实都是传值,不同的只是一个是*p ,一个是p)
我们java程序员控制对象的时候操作的是对象的引用,引用中存放着一个值,通过这个值你可以找的到它所指向的对象的位置。对象和引用不一样,引用是固定大小的,类似C中的指针变量,用来指定对象的位置,而对象需要分配的地址空间和其的属性有关,当然了,如果包含一个对象A属性的话,对象里面存放的也只是该属性A的引用而已。现在让我们看另外一个例子:
package com.king.chat.test;
public class ObjectParamTest {
private int id ;
private String name ;
public ObjectParamTest(int id ,String name)
{
this.id = id ;
this.name = name ;
}
public void getId() {
System.out.println(id);
}
public void setId(int id) {
this.id = id;
}
public void getName() {
System.out.println(name);
}
public void setName(String name) {
this.name = name;
}
public String toString(){
return "id=" + id +",name=" +name ;
}
public static void ChangeObj1(ObjectParamTest o){
o.setId(20); //更改的是引用的值
o.setName("zazaking"); //更改的是引用的值
System.out.println(o);
}
public static void ChangeObj2(ObjectParamTest o){
o = new ObjectParamTest(100 ,"guest");//更改了引用的地址
}
public static void main(String[] argc){
ObjectParamTest o = new ObjectParamTest(10 ,"king");
System.out.println(o);
ChangeObj1(o);
System.out.println(o);
ChangeObj2(o);
System.out.println(o);
}
}
这个例子输出的结果是 id=10,name=king
id=20,name=zazaking
id=20,name=zazaking
id=20,name=zazaking
这个例子分为两部分,第一部分是对对象内部的属性的改变,第二部分是对整体对象的改变
前面我们已经说过,java中真正对对象的操作,首先得通过指向它得引用中的值
对象的实参和行参的对照:
Id Addr Value state
实参 K 0x00001 0x11111 1
行参 I 0x00005 0x11111 2
从上表中可以发现传递了对象时,实参和行参虽然占用着不同的内存,但是他们的Value通过值传递被赋予了相同的值,所以通过Value所指向的Object也是同一个, 当然了,我们对行参I的操作有两种,一种就是直接对Addr的赋值(代码的第二部分),另一种是对Value的操作(代码的第一部分)
举例:
有两兄弟,没有结婚前他们和父母一起拥有着一个共同的家,有一天,弟弟说自己家里安了电话,其实也就代表了哥哥家里安了电话,结果是一样的.(第一部分) ,哪天哥哥结婚了,有了一个自己的家,这时候,哥哥的家和弟弟的家指向的就不是同一个了,忽然有一天哥哥哭丧了个脸说家里被盗了,当然不可能代表弟弟的家也被盗了.