在Java中,变量分为两类:
1.基本类型变量,java是传递的副本
2.一切对象型变量,传引用副本的实质是复制指向地址的指针
a.基本类型引用
public class BasicTransmit { public static void test(boolean test){ test =! test; System.out.println("in test : test = "+test); } public static void main(String[] args) { boolean test = true; System.out.println("Before test : test = "+ test); test(test); System.out.println("After test : test = "+test); //在java中,对于基本类型变量(int,long,double,float,byte,boolean,char) //java 是传值的副本. } }
运行结果是:
Before test : test = true
in test : test = false
After test : test = true
b.对象的引用(String不是基本数据类型,而是对象)
public static void test (StringBuffer str){ str.append(",wrold!"); } public static void main(String[] args) { StringBuffer string = new StringBuffer("Hello"); test(string); System.out.println(string); //意料之中,String是一个引用,java对于引用形式传递对象类型的变量是,实际上是将引用 //作为一个副本传递方法函数.那么这个函数里面的引用副本所指向的是什么? //是对象的地址,通过引用副本找到地址并修改地址的值,也就修改了对象的值 }
运行结果:Hello,wrold!
public static void test (String str){ str = "world"; } public static void main(String[] args){ String string = "Hello"; test(string); System.out.println(string); } //为什么会这样呢?这是因为当执行str="world"时,过程为:首先系统会自动生成应新的string对象 //并把这个新对象的值设为"world",然后把这个对象的引用赋给str //理解:为str这个钥匙原来是指向"hello"这个仓库的,但是现在要求str这个钥匙重新指向"world" //我们必须清楚一点是:String类是final类型的,因此,你不可以继承和修改这个类. //str="world",其实是隐含地让java生成一个新的String对象,既然对象都是新的,那就与原来的 //"Hello"没有任何关系. //当函数结束,str作用消失,原来的内存地址上的内容未加改变,所以打印结果仍然是Hello //StringBuffer产生的一块内存空间,相关的增删改操作都在其中进行,所以为其添加一句"world" //仍然是在同一段内存地址上进行的,str所值向的引用并没有改变.
c.对象的引用
public class ValueTest { public void first(){ int i = 5; Value v = new Value(); v.i = 25; second(v ,i); System.out.println(v.i); } public void second(Value v ,int i){ i = 0; v.i = 20; Value val = new Value(); v= val; System.out.println(v.i + "" + i); } public static void main(String[] args) { ValueTest t = new ValueTest(); t.first(); } } class Value{ public int i = 15; }
结果是:15 0 20
总结:在java中无论是基本数据类型还是对象都是引用的副本或者地址的副本,当返回本函数是,值是没有变化的.除非在函数运行中已经把本地址指向的空间内的值修改了.