java传参数的原理:
//
1. 对于基本类型 int, long, char, float, double等,是传值的。就是
int a = 0;
func(a);
这里无论func对参数a做了什么操作,在函数体外a都不受任何影响。
2. 对于对象类型,如StringBuffer, String,Integer等,在作为函数的参数的时候传过来的是一个对象实例的引用。说白了就是复制了一个对象的地址进来。比如:
String a = "ABC";
func(a);
void func(String s){
s="BCD";
}
这里的话,当a作为参数传给func的时候,func里面的初始化类似会做一步:String s=a的操作,那么一个新的String对象引用s将会被创建,而s指向的是原来a指向的内容。那么s和a都会操作同一个堆里面的对象了。但是为什么s="BCD"以后,外面的a的值还是"ABC"呢?那是因为执行完 s="BCD"之后,s已经指向另外一个字符串常量了,当然不会对a造成影响。
其实出现这样的误会很大程度在于String类型的特殊性。其实一个string的对象被new出来以后,它的这块内存里面的内容是不会被改变的了(其实String类压根没有提供方法给你修改,你看到的replace和concat方法都没有改变这个String本身)。所以你把这块内存的引用放到函数里面去,其实都是没有办法修改的,只能新建立 一些string的内存引用。而其它类型,因为是能够操作堆里面的对象的内容的,所以使用引用对这些对象进行修改的时候,就能影响到函数外面的另外一个引用了。
///
下面以最终的效果来解释参数的传递方式:
1、对于原始数据类型,也就是int、 long、char之类的类型,是传值的,如果你在方法中修改了值,方法调用结束后,那个变量的值没用改变。
2、对于对象类型,也就是Object的子类(java中object是全部对象的超类),如果你在方法中修改了它的成员的值,那个修改是生效的,方法调用结束后,它的成员是新的值,但是如果你把它指向一个其它的对象,方法调用结束后,原来对它的引用并没用指向新的对象。
代码如下:
public class Tester {
public static void main(String[] args) {
int primitive = 2;
changePrimitive(primitive);
//primitive的值依然是2
MyClass myClass = new MyClass();
changeObject(myClass);
//myClass仍然指向的是执行changeObject之前的那个对象
//但是myClass.i等于3了
}
public static void changePrimitive(int primitive) {
primitive = 3;
}
public static void changeObject(MyClass myClass) {
myClass.i = 3;
myClass = new MyClass();
}
}
class MyClass {
int i;
}
对于远程调用,无论是什么类型,调用结束后,传入的参数和以前没用任何变化(当然前途是直接调用远程方法,如果中间经过其它的Proxy类或者Facade类,不能保证那些类对对象没用修改)。至于是通过Local接口进行调用的,也应该属于本地调用,和上面说的情况应该是一致的。
//