Bits for u

Question: Does Java pass objects by reference or by value?

Answer:
Since it makes no sense to begin any argument without agreed upon defintions let's formally define our terms. I will use abstract pseudocode to keep the issue from being clouded by the idiom of a particular language. The source of my information is the book "Advanced Programming Language Design" by Raphael A. Finkel.

For those unfamiliar with the term below an L-value is an expression that can appear on the left side of an assignment statement. It is basically a way to address where a variable is stored. Variables and other ways to refer to locations in memory are L-values. Most expressions are not L-values, e.g. ( x * 2 )

We assume the presence of a procedure named f that takes a formal parameter s. We call that function giving it an actual parameter g.

The calling code:

      f( g )
The function:
procedure f( s )
begin
-- body of the procedure
end;
There are several parameter passing semantics that have been proposed or used:
value
The value of the actual parameter is copied into the formal parameter when the procedure is invoked. Any modification of the formal parameter affects only the formal parameter and not the actual parameter. This is the most common form of parameter passing and is the only one provided in C and Java.
result
The value of the formal parameter is copied into the actual parameter when the procedure returns. Modifications to the formal parameter do not affect the formal parameter until the function returns. The actual parameter must be an L-value. It is usually invalid to pass the same L-value to more than one result parameter, but the compiler cannot always detect this. The best example of this is out parameters in CORBA.
value result
Combination of value and result semantics. The best example of this are inout parameters in CORBA.
reference
The L-value of the formal parameter is set to the L-value of the actual parameter. In other words, the address of the formal parameter is the same as the address of the actual parameter. Any modifications to the formal parameter also immediately affect the actual parameter. FORTRAN only has reference mode (expressions are evaluated and stored in a temporary location in order to obtain an L-value). C++ has reference parameters by putting a & before the formal parameter name in the function header. Reference mode can be simulated in C using pointers and adding the & to the actual parameter and dereferencing the formal parameter within the function.
readonly
Can use either value or reference mode, but modification of the formal parameter is forbidden by the compiler.
macro
name
These two have been used in the past, but are very much out of favor because they are confusing and difficult to implement. Therefore I won't bother trying to explain them.

Now that we have some definitions of terms we can return to the question. Does Java pass objects by reference or by value?

The answer is NO! The fact is that Java has no facility whatsoever to pass an object to any function! The reason is that Java has no variables that contain objects.

The reason there is so much confusion is people tend to blur the distinction between an object reference variable and an object instance. All object instances in Java are allocated on the heap and can only be accessed through object references. So if I have the following:

StringBuffer g = new StringBuffer( "Hello" );
The variable g does not contain the string "Hello", it contains a reference (or pointer) to an object instance that contains the string "Hello".

So if I then call f( g ), f is free to modify its formal parameter s to make it point to another StringBuffer or to set it to null. The function f could also modify the StringBuffer by appending " World" for instance. While this changes the value of that StringBuffer, the value of that StringBuffer is NOT the value of the actual parameter g.

Imagine for instance if I set g to null before passing it to f. There is no StringBuffer now to modify and f can in no way change the value of g to be non-null.

The bottom line is Java only has variables that hold primitives or object references. Both are passed by value.

There are good reasons that Java excluded the idea of pass-by-reference from its language design, and when writing Java applications it's best to do as Java does. There are elegant solutions to all common problems that may be solved with pass-by-reference in other languages. Before I get there, though, let's look at some of the problems of pass by reference.

Pass by reference mixes inputs and outputs of code. This is the fundamental problem with the technique. In Java, a programmer can assume that variables will not change their value when passed as parameters to a method. In languages with pass by reference semantics, this basic assumption cannot be made.

Pass by reference confuses the interface to a method. Methods written using pass-by-reference semantics can have extremely complex interfaces that are difficult for client programmers to learn and understand. That said, you may be left with a situation where you feel the need to use pass-by-reference in an application. There are two major reasons to use pass by reference, and each has its own solution:

First, pass by reference is used in many languages to reduce the costs of a method call, preventing the copying of large amounts of data. This is a non-issue in Java. The problem is solved by simply realizing that in Java, the values passed to a method are either primitive data or object references, which cannot be large enough to make this a real issue. Objects themselves can be very large, but are never passed to methods.

Second, pass by reference allows the variable to be changed, and the changed value can be seen in client code. The solution here is to refactor the application to use the return value for this purpose. If a parameter is an "in-out" parameter, then its original value should be passed into the method and its result moved to the return value. The client code may then look like this:

    a = someMethod(a);
This immediately, of course, brings up the problem of multiple return values. Java does not allow them, so only one value can be returned from a method. It's far easier to treat this problem when it's cast as a way to handle the need for multiple return values, rather than a need for pass-by-reference.

http://www.yoda.arachsys.com/java/passing.html#formal

Comments

Anonymous said…
Vetri, That was a cool cool explanation da ..
"Objects , however are not passed at all "
..is fundoo ..

Keep going ..
Dei madooo.. too gud man..

Even i dint have a second thought about the myth - "Objects are passed by reference, primitives are passed by value".. Makes more sense after reading ur explanation ...

Very good research & explanation. keep going da..

Popular posts from this blog

BIP Formatting

Repeat Table Header in all pages in BIP

Limit rows per page