其实这个问题我原来翻译(破除java神话之二:参数是传址的 )、转帖别人的详细解释(Java 应用程序中的按值传递语义 )和专门解释( 我对《Java 应用程序中的按值传递语义》的理解 )过,不过现在看来,原来翻译或者解释的角度是有问题的,从底层的角度解释并不直观,在交流的时候也容易引起误解,最终不能达成一致意见。下面以最终的效果来解释参数的传递方式:
1、对于原始数据类型,也就是int、 long、char之类的类型,是传值的,如果你在方法中修改了值,方法调用结束后,那个变量的值没用改变。
2、对于对象类型,也就是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接口进行调用的,也应该属于本地调用,和上面说的情况应该是一致的。
2006年11月15日 at 17:46
local 调用相当于同一个虚拟机上的对普通对象方法的调用。
上面那段代码眼熟啊,上个月做过,哈哈。
2006年11月16日 at 16:25
local调用可能是本地调用,但是感觉有可能会换成远程调用,这样如果没有意识到,可能会有潜在的bug。因为本地调用和远程调用的特性是不一样的。可能会误用特性。
2006年11月22日 at 17:40
针对这个问题,我根据自己的理解写了一篇心得: 用”堆栈区数据复制”理解Java赋值和参数传递机制的心得( http://java.learndiary.com/disDiaryContentAction.do?goalID=2716 )
有兴趣的朋友可以帮忙评一评是否正确或准确。
2006年11月22日 at 17:53
你的理解应该没有问题,但是好像还是比较拗口,还是以底层的机制在进行解释,很多人可能还是理解不了或者理解有困难。 :em20:
另外没有提及远程调用的方式。
2006年11月22日 at 18:00
PS:你的网站注册后才能回复?
2006年11月22日 at 18:26
谢谢Cherami的意见。
远程调用我不懂。所以现在无法与你深入交流。
我猜想:在远程调用中,应该有4个层次吧,客户端的具体请求部分,客户端的网络接口部分,服务端的网络接口部分,服务端的具体实现部分。
客户端的具体请求部分和客户端的网络接口部分的交互和服务端的网络接口部分和服务端的具体实现部分的交互,我想是应该纳入我那篇心得的范围,而至于网络接口之间的交互,我猜想可能对于我们写程序的人是透明的吧?
仅仅是猜想:)
2006年11月22日 at 18:28
> PS:你的网站注册后才能回复?
是的。我知道应该改,不过有点懒,没改。我想现在多学习,写网站的事缓了缓。
2007年7月27日 at 14:29
class MyClass {
int i;
}
应该为
static class MyClass{
int i;
]
吧,不然内部类无法实例化,若理解有误还请指正
2007年7月27日 at 20:42
MyClass不是内部类,而是一个普通类。
一个类文件里面可以定义很多类的,但是只能有一个是public的。