Discussion:
java 沒有 pass-by-reference 那麼另人難接受嗎?
(时间太久无法回复)
嵐雲
22 years ago
Permalink
pass-by-xx 是 progamming lanuague 裏,
有關參數傳遞方式的一種分類,
就那分類的定義,
java 沒有 pass-by-reference,
而是 pass-by-value,

不管是 java 的技術文件也好,
java 的 tutorial 也好,
(前面都有給過 URL)
都說 java 沒有 pass-by-reference,
而是 pass-by-value,
這那麼另人難接受嗎?

再從 PL 定義來看 java 的機制,

Programming language 對 pass-by-refernece 的定義.
"
Pass by reference is a second implementation model for inout-mode
parameters. Rather than transmittting data values back and forth,
however, as in pass-by-value-result, the pass-by-reference method
transmits an access path, usually an addesss, to the called subprogram.
This provides the access path to the cell storing the actual parameter.
Thus the called subprogram is allowd to acesss the actual paramter in
the calling program. In effect, the actual parameter is shared with the
called subprogram.
"
java 文件
http://java.sun.com/docs/books/jls/second_edition/html/typesValues.doc.html

4.5.2 Variables of Reference Type

A null reference
A reference to any object (§4.3) whose class (§4.5.6) is assignmen
t compatible (§5.2) with the type of the variable

4.3.1 Objects
An object is a class instance or an array.
The reference values (often just references) are pointers to
these objects, and a special null reference,
which refers to no object.



java reference type 的 variable(變數),
存的是一個 reference value, 指到 object,
也就是 recerence type variable 的 value 是指到一個
object.
改變一個 refernce type 的 variable 的值,
意義是那個 variable 指到不同的 object,
而不是改變 object 裏的內容.

當做 methoad call 時,
參數(actual parameter) 是 refernce type 的 variable 時,
(
"the pass-by-reference method
transmits an access path, usually an addesss, to the called subprogram."
)
java 在 method call , 有沒有 pass 那個 variable 的 access path,
到被呼叫的 method 裏? 沒有.
java 是把 variable 的值, 指到 object 的那個 reference value 傳到 method 裏.
只是 pass-by-value,
讓在 method call 裏, 那個參數變數的 value 等於 actual parameter 的 value,
也就是讓 method call 裏的變數所指向的 object,
等於是 actual parameter 上那個變數所指向的 object 是同一個.
是把變數的值傳進去, 該二個變數指向同一個物件.

"This provides the access path to the cell storing the actual parameter"
java 在 method 裏, 有沒有辦法去 access 到 actual parameter?
那個 refernce type 的 variable?
不能.
java 只是能 access 到 actual parameter 的值, 所指到的 object,
而不是能 access 到 actual parameter 的那個 variable.
也就在 method call 裏, 無法去改變 actual parameter 的值,
也就是, 無法讓 actual parameter 的變數, 指到不同的 object.

(
在 c 裏, 還有個 & 的 operator, 可以取到一個 variable 的 "access path",
所以利用 &, 可以把一個 varialbe的 access path 取出來,
成為模擬 pass-by-reference, 有人稱之為 explicit pass-by-reference.
但是, 那個還是不叫 pass-by-refernce, 因為
actual parameter 是 &variable, 不是 variable.
pass 的 是一個 variable 的 unary operator 運算結果的一個 value.
更不用說, 在 java 根本沒有任何方式可取到一個 variable 的 "access path".
)

或許你認為這個只是一些賣弄名詞,
那你錯了...

在我學習的過程中,
很多事情, 當時再怎麼解釋還是不懂, (或許我比較笨),
但是我會記下各種說法,
到有一天真正用到時, 就會頓然明白.

不要在你還一知半解時,
就要硬套上一個答案..


--
※ Origin: 鳥窩 (BirdNest.twbbs.org) ◆ From: u159-106.u61-70.giga.net.tw
嵐雲
22 years ago
Permalink
又找到一份 faq 文件,
http://www.javaworld.com/javaworld/javaqa/2000-05/03-qa-0526-pass.html
這份 faq 文件有舉例, 也有畫圖,
說明 java 是 pass-by-value, 不是 pass-by-refernce,
如果是 pass-by-refernce, 那麼
情況會是如何...
那個例子的 code 的結果會是不一樣.


"Java manipulates objects 'by reference,'
but it passes object references to methods 'by value.'"
As a result, you cannot write a standard swap method to swap objects.

~
--
※ Origin: 臺大電機 Maxwell 站 ◆ From: u159-106.u61-70.giga.net.tw
嵐雲
22 years ago
Permalink
※ 引述《***@BirdNest.twbbs.org (嵐雲)》之銘言:
: pass-by-xx 是 progamming lanuague 裏,
: 有關參數傳遞方式的一種分類,
: 就那分類的定義,
: java 沒有 pass-by-reference,
: 而是 pass-by-value,
: 不管是 java 的技術文件也好,
: java 的 tutorial 也好,
: 都說 java 沒有 pass-by-reference,
: 而是 pass-by-value,


又找到一份 faq 文件,
http://www.javaworld.com/javaworld/javaqa/2000-05/03-qa-0526-pass.html
這份 faq 文件有舉例, 也有畫圖,
說明 java 是 pass-by-value, 不是 pass-by-reference,



可以看一下那個圖,
pnt1, pnt2 是傳進去的 actual paramter,
pnt1, pnt2 是兩個變數, 它的值,
指向那二個 object,


在 method call 裏,
arg1, arg2 是接受參數的二個變數,
一開始 (before tricky),
pnt1=arg1 指向同樣的 object,
pnt2=arg2 指向同樣的 object,
而在之後 (after tricky),
arg1 跟 arg2 的值互換了,
但 pnt1 跟 pnt2 沒有,
所以變成 pnt1 跟 arg2 指向同樣的 object,
而 pnt2 跟 arg1 指向同樣的 object.
如果說, java 是 pass-by-reference,
那麼在 after tricky 之後,
pnt1 跟 pnt2 的值應該也要互換.



"Java manipulates objects 'by reference,'
but it passes object references to methods 'by value.'"
As a result, you cannot write a standard swap method to swap objects.

--
※ Origin: 臺大電機 Maxwell 站 ◆ From: u159-106.u61-70.giga.net.tw
嵐雲
22 years ago
Permalink
※ 引述《***@BirdNest.twbbs.org (嵐雲)》之銘言:
: pass-by-xx 是 progamming lanuague 裏,
: 有關參數傳遞方式的一種分類,
: 就那分類的定義,
: java 沒有 pass-by-reference,
: 而是 pass-by-value,
: 不管是 java 的技術文件也好,
: java 的 tutorial 也好,
: 都說 java 沒有 pass-by-reference,
: 而是 pass-by-value,


又找到一份 faq 文件,
http://www.javaworld.com/javaworld/javaqa/2000-05/03-qa-0526-pass.html



可以看一下那個圖,
pnt1, pnt2 是傳進去的 actual paramter,
pnt1, pnt2 是兩個變數, 它的值,
指向那二個 object,


在 method call 裏,
arg1, arg2 是接受參數的二個變數,
一開始 (before tricky),
pnt1=arg1 指向同樣的 object,
pnt2=arg2 指向同樣的 object,
而在之後 (after tricky),
arg1 跟 arg2 的值互換了,
但 pnt1 跟 pnt2 沒有,
所以變成 pnt1 跟 arg2 指向同樣的 object,
而 pnt2 跟 arg1 指向同樣的 object.
如果說, java 是 pass-by-reference,
那麼在 after tricky 之後,
pnt1 跟 pnt2 的值應該也要互換.



Java does manipulate objects by reference, and all object variables are references.
However, Java doesn't pass method arguments by reference; it passes them by value.

"Java manipulates objects 'by reference,'
but it passes object references to methods 'by value.'"
As a result, you cannot write a standard swap method to swap objects.


上面除了這句話,
"Java doesn't pass method arguments by reference"
其它的 reference 都是在指 java 的 refernce.
而這句話, 有 passs 有 by reference,
尤其又提到 arguments(或是說 parameter, 參數)
它的 reference 只的就不是 java 的 reference,
把 pass by reference 擺一起看,
在講 PL 裏的參數傳送方式.
--
※ Origin: 臺大電機 Maxwell 站 ◆ From: u159-106.u61-70.giga.net.tw
Terry
22 years ago
Permalink
※ 引述《EightCloud (嵐雲)》之銘言:
哈......都一把年紀了, 還在這吵這個每年一度的大事, 實在是不得不配服
反正, 你要說的是,Pascal, Modula-2 and Algol-68. 才有call by reference
因為它bind 的是l_value, 不是r_value
這樣子清楚明瞭, 看不懂的人自己去看書.
年紀大了, 火氣還哪麼大, 真是不錯!
--
※ Origin: 臺大電機 Maxwell 站 ◆ From: u199-174.u203-204.giga.net.tw
熾翼
22 years ago
Permalink
【 在 ***@bbs.ee.ntu.edu.tw (嵐雲) 的大作中提到: 】
: ※ 引述《***@BirdNest.twbbs.org (嵐雲)》之銘言:
: 又找到一份 faq 文件,
: http://www.javaworld.com/javaworld/javaqa/2000-05/03-qa-0526-pass.html
: 這份 faq 文件有舉例, 也有畫圖,
: 說明 java 是 pass-by-value, 不是 pass-by-reference,
: 可以看一下那個圖,
: pnt1, pnt2 是傳進去的 actual paramter,
: pnt1, pnt2 是兩個變數, 它的值,
: 指向那二個 object,
: 在 method call 裏,
: arg1, arg2 是接受參數的二個變數,
: 一開始 (before tricky),
: pnt1=arg1 指向同樣的 object,
: pnt2=arg2 指向同樣的 object,
: 而在之後 (after tricky),
: arg1 跟 arg2 的值互換了,
: 但 pnt1 跟 pnt2 沒有,
: 所以變成 pnt1 跟 arg2 指向同樣的 object,
: 而 pnt2 跟 arg1 指向同樣的 object.
: 如果說, java 是 pass-by-reference,
: 那麼在 after tricky 之後,
: pnt1 跟 pnt2 的值應該也要互換.
: "Java manipulates objects 'by reference,'
: but it passes object references to methods 'by value.'"
: As a result, you cannot write a standard swap method to swap objects.
Java:
X: 10 Y: 0
X: 0 Y: 5

X: 100 Y:100
X: 0 Y: 5

C++ call by address
X: 10 Y: 0
X: 0 Y: 5

X: 100 Y:100
X: 0 Y: 5

C++ call by refrence
X: 10 Y: 0
X: 0 Y: 5

X: 0 Y:5
X: 0 Y: 5

程式碼如下:
C++ call by addr.
#include <iostream>
using namespace std;

class Point
{

public:
Point(int x1,int y1)
{
x=x1;
y=y1;
}
int x;
int y;
};

void tricky(Point *arg1, Point *arg2)
{
arg1->x = 100;
arg1->y = 100;
Point *temp = arg1;
arg1 = arg2;
arg2 = temp;
}

void main()
{
Point *pnt1 = new Point(10,0);
Point *pnt2 = new Point(0,5);
cout<<"X: "<< pnt1->x<< " Y: "<<pnt1->y<<endl;
cout<<"X: "<< pnt2->x<< " Y: "<<pnt2->y<<endl;
cout<<" "<<endl;
tricky(pnt1,pnt2);
cout<<"X: "<< pnt1->x<< " Y:"<< pnt1->y<<endl;
cout<<"X: "<< pnt2->x<< " Y: "<<pnt2->y<<endl;
}
------------------------------------
C++ call by reference
#include <iostream>
using namespace std;

class Point
{

public:
Point(int x1,int y1)
{
x=x1;
y=y1;
}
int x;
int y;
};

void tricky(Point &arg1, Point &arg2)
{
arg1.x = 100;
arg1.y = 100;
Point &temp = arg1;
arg1 = arg2;
arg2 = temp;
}

void main()
{
Point pnt1(10,0);
Point pnt2(0,5);
cout<<"X: "<< pnt1.x<< " Y: "<<pnt1.y<<endl;
cout<<"X: "<< pnt2.x<< " Y: "<<pnt2.y<<endl;
cout<<" "<<endl;
tricky(pnt1,pnt2);
cout<<"X: "<< pnt1.x<< " Y:"<< pnt1.y<<endl;
cout<<"X: "<< pnt2.x<< " Y: "<<pnt2.y<<endl;
}

--
※ 來源:‧四百年來第一站 firebird.cs.ccu.edu.tw‧[FROM: net06.cs.ccu.ed]
嵐雲
22 years ago
Permalink
: C++ call by addr.

void tricky(Point *&arg1,Point *&arg2);
如果你要寫那 java 對應的 c++ 且是 pass-by-reference.

c++ 的 class type variable 跟 java 的不一樣,
c++ 的 class type variable 是 object 本身,
不是指到 object 的一個 reference,
pointer to class type variable 才是類似 java 的
class type variable.


: void tricky(Point &arg1, Point &arg2)
: {
: arg1.x = 100;
: arg1.y = 100;
: Point &temp = arg1;

要用這種方式寫 tricky,
這裏不能用 Point &temp = arg1;
要用 Point temp=arg1;

: arg1 = arg2;
: arg2 = temp;
: }
--
※ Origin: 臺大電機 Maxwell 站 ◆ From: h201-210-243-200.seed.net.tw
Loading...