作者sbrhsieh (偶尔想摆烂一下)
看板java
标题Re: [问题] java的call by reference
时间Fri Apr 9 00:40:23 2010
※ 引述《neigence ()》之铭言:
: 首先 先来个简单到爆表的程式 大家都知道 下面的程式一定会发生
: null pointer exception
: public class Factory{
: public Factory(){
: Object obj = null;
: createObject(obj);
: }
: public void createObject(Object obj){
: obj = new Object();
: }
: public static void main(String args[]){
: new Factory();
: }
: }
: 这边的例外 相当理所当然,但我最近在想 java 不是 call by reference的吗
: [略]
: 这边我pass pointer 的 reference到 function dodo,但却正常运作了
: 难道!?! java不是这样运作的????
我个人觉得以 pass by value 来唯一描述 Java method invocation 的 argument
传递行为比较恰当,然而屡次观看这个议题的辩论时,我总是思索不接受的这个看
法者的心态会是如何地不同意此看法,关於这我现在还是不很了解。
但是现在若我要与 Java programmer(特别是纯 Java programmer)讨论这个议题,
我会劝对方不要去管到底是 pass by value 还是 pass by reference。
只要 Java programmer 真正了解 primitive type value 与 reference type
value 在本质上的区别(例如前者支援 arithmetic 操作/不支援隐含 dereference
语意的操作,後者反之..等等),并且了解 assignment operator 的语意的话,
到底要说是 pass by value 还是 pass by reference 一点也不重要,实际上如果
扣除 primitive/reference type value 本质上的差异造成的影响,argument 是
primitive type 或是 reference type 在行为上是相等的,特地区分 primitive
type argument 是 pass by value、reference type argument 是 pass by
reference 是不是显得没有意义,因为名称的不同只是因为 argument 的型态不同。
以上面的程式码来说,可以把 createObject inline 在 Factory constructor
里。Method invocation 隐含有 asignment 在 actual argument 与对应的 formal
parameter 之间,对於一个 method 宣告如下:
R foo(T1 p1, T2 p2,..., Tn pN)
在 inline 到如下的 method invocation expression(statement) 时:
foo(expr1, expr2,..., exprN);
在 method code inline 部份的最前头加上:
T1 p1 = expr1;
T2 p2 = expr2;
...
Tn pN = exprN;
那麽 Factory constructor 在 inline createObject method
後成了:
public Factory(){
Object obj = null;
Object pObj = obj;
pObj = new Object();
System.out.println(obj.toString());
}
对於最後一个 statement 会产生 NullPointerException 我相信多数的 Java
programmer 应该都能理解(且自然,不然就是尚未了解 assignment 语意)。
现在试着假设有两个 method,其一有一个 primitive type parameter,另一有
一个 reference type parameter。对於 primitive/reference type variable,
其共通的操作(且有 side effect) 只有 assigment 与 casting。以 assignment
操作来举例,可使用以下两个片断来简单通用地描述此二 method invocation
inline 後的结果:
int a = 0;
int b = a;
b = 10;
System.out.println(a);
**************************************************
Object a = null;
Object b = a;
b = "Hello";
System.out.println(a);
从结果来看,两者的行为特性并无不同,显示出 pass primitive value 与 pass
reference value 到 method 是相同的。那麽有必要强调 primitive type argument
是采 pass by value,reference type argument 是采 pass by reference 吗?
如果不排除 primitive/reference type 本质上的差异,就会有一堆试图说明
primitive/reference argument 是分别透过 pass by value/pass by reference
,以及两者在行为特性上有何差别的例子。这些例子我都可以透过 inline 的方式
举出对等的例子(出现相同行为特性),但是不牵涉到 method invocation。
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 218.173.136.159
※ 编辑: sbrhsieh 来自: 218.173.136.159 (04/09 00:45)
※ 编辑: sbrhsieh 来自: 218.173.136.159 (04/09 00:59)