pass by reference

A

angelochen960

Hi,

what is the equivalent of Java approach to this C++ function:

public void myFunc(String &s) {
s = "123";
}

I'd like to define a method where several values can be returned. any
idea?

Angelo
 
D

Donkey Hot

Hi,

what is the equivalent of Java approach to this C++ function:

public void myFunc(String &s) {
s = "123";
}

I'd like to define a method where several values can be returned. any
idea?

Angelo

public void myFunc(String s) {
s = "123";
}

In java, all objects are passed by reference.

Basic data types like int, long, boolean are passed by value. Object
variables are always references to an object, and the reference is passed
"by value" as the basic data types, but it is a reference, so...
 
R

Roedy Green

I'd like to define a method where several values can be returned. any
idea?

1. you pass in an object, and you set fields on that object.

2. you create a new object with several fields and return that.

You can't change any of your caller's variables, just the fields in
the objects they point to.
 
R

rmoldskr+usenet

Donkey Hot said:
public void myFunc(String s) {
s = "123";
}

This won't work, though. While the String object s' is passed by reference,
the _reference_ s is passed by value. Any changes made to the reference in
the subprogram -- such as changing the object it points to -- will not have
any effect on the main program.

public class Demo {
private static final STRING_1 = "String_1";
private static final STRING_2 = "String_2";

public void outer( ) {
String workString = STRING_1;
change( workString );
// workString is still pointing to STRING_1
}

public void change( String stringToChange ) {
stringToChange = STRING_2;
}
}

If the argument is a mutable type (unlike String), you can get the required
effect by modifying (rather than reassigning) the object:

public class Demo2 {
private static final STRING_1 = "String_1";
private static final STRING_2 = "String_2";

public void outer( ) {
StringBuffer workString = new StringBuffer( STRING_1 );
change1( workString );
// workString now equals "String_2"
change2( workString );
// workString _still_ equals "String_2"
}

public void change1( StringBuffer stringToChange ) {
stringToChange.delete( 0, stringToChange.length( ) );
stringToChange.append( STRING_2 );
}

public void change2( StringBuffer stringToChange ) {
// This won't work, as the change to the reference is
// lost when the method returns
stringToChange = new StringBuffer( STRING_1 );
}
} // end class


If you have an immutable type or need to create a whole new object for some
other reason, you'll need to use some kind of wrapper. Either a
data-structure or an array:

public void change( String[] stringWrapper ) {
stringWrapper[0] = STRING_2;
}


private static final class ChangeData {
public String toBeChanged;
}

public void change( ChangeData data ) {
data.toBeChanged = STRING_2;
}
 
C

Chase Preuninger

All objects are "passed by reference" and all primitive types have
their value copied.
 
S

Stefan Ram

I'd like to define a method where several values can be
returned. any idea?

According to the JLS, methods are »declared«.

»You can't return more than one value from a method. If
you want to, you have to return a little array (unless one
value is an int and the other is a Person!) or an object
of some special little class made just for this purpose.
When I was helping Bill Joy and Guy L. Steele Jr. by
reviewing drafts of the original Java Language
Specification, I was originally upset that there was no
way to do this. So I set out to find a small example
program that obviously demanded such a feature, to
convince them that multiple value returns must be added. I
was unable to come up with one, and I could see that
Java's philosphy was to leave out things that are rarely
used and not crucial, so finally didn't say anything.«

Dan Weinreb's Weblog

http://dlweinreb.wordpress.com/category/java/

I have written several programs myself to show how multiple
returns might be emulated in Java. Each approach has its
advantages and disadvantages. I might add that, whenever I
want to achieve something with Java, the lack of explicit
multiple return values is not a problem for me.

So, here are my notes:

I assume a simple multiple-return task such as, in pseudocode:

operation "sumdiff"
in x, y;
out sum, difference;
{ sum = x + y; difference = x - y; }

Solution with public fields:

class Sumdiff
{ public Sumdiff( final int x, final int y )
{ this.sum = x + y; this.difference = x - y; }
public final int sum; public final int difference; }

public class Main
{ public static void main( final java.lang.String[] args )
{ final Sumdiff result = new Sumdiff( 4, 2 );
java.lang.System.out.println
( result.sum + ", " + result.difference ); }}

6, 2

If you do not like public fields, you might use getters
as well.

A »processor object« can be created once and be used
several times:

public class Main
{ public static void main( final java.lang.String[] args )
{ final Processor processor = new Processor();
processor.set( 4, 2 );
processor.calculateSumDiff();
java.lang.System.out.println( processor.getSum() );
java.lang.System.out.println( processor.getDifference() );
processor.set( 8, 4 );
processor.calculateSumDiff();
java.lang.System.out.println( processor.getSum() );
java.lang.System.out.println( processor.getDifference() ); }}

class Processor
{ public void set( final int x, final int y )
{ this.x = x; this.y = y; }
public void calculateSumDiff()
{ this.sum = x + y; this.difference = x - y; }
public java.lang.Integer getSum(){ return sum; }
public java.lang.Integer getDifference(){ return difference; }
int x; int y; int sum; int difference; }

To avoid allocation overhead of a result object,
the client might provide and reuse such an object:

class Result { public int x; public int y; }

class Server
{ void run( final Result result, final int x, final int y )
{ result.x = x + y; result.y = x - y; }}

public final class Main
{ private static Result result = new Result(); /* single allocation */
public static void main( final java.lang.String argv[] )
{ Server server = new Server();
server.run( result, 1, 2 );
java.lang.System.out.println( result.x );
java.lang.System.out.println( result.y );
server.run( result, 3, 4 );
java.lang.System.out.println( result.x );
java.lang.System.out.println( result.y ); }}

One can also emulate multiple returns via multiple
arguments, but only when adopting a »continuation passing
style«. In the next example, the server »returns« a pair
of random numbers to the client, by calling back a method
provided by the client.

interface Client { void continuation( int x, int y ); }

class Server
{ static java.util.Random rand = new java.util.Random();
static void getPair( final Client client )
{ client.continuation( rand.nextInt( 11 ), rand.nextInt( 21 )); }}

class Example implements Client
{ public void continuation( final int x, final int y )
{ java.lang.System.out.println( x + ", " + y ); }
public void main()
{ Server.getPair( this ); }}

public class Main
{ public static void main( final java.lang.String[] args )
{ new Example().main(); }}

But, as said, I rarely ever (actually: never) have needed any
of these multiple return value emulations in my own projects.

Possibly this is because I already have accounted for the
properties and limitations of Java when I was designing
my classes. So I have designed them from the start in such
a way that multiple return values are not needed.
 
A

Andreas Leitgeb

Chase Preuninger said:
All objects are "passed by reference" and all primitive types have
their value copied.

The objects are indeed passed by reference.

There is a fundamental difference between C++ and Java
with respect to the assignment-operator.

In C++, assignment is the Object's business,
so, passing an object into a function and assigning
to it inside, will change the value of that object,
and thus be visible outside.

In Java, assignment (with "="-operator) does not
change the referenced Object, but replace it, by
changing only the reference.
This effect, however, is not visible outside,
because it's only the Object, but not the reference
itself, that is passed "by ref".
 
L

Lew

Chase said:
All objects are "passed by reference" and all primitive types have
their value copied.

As others have stated and illustrated in this thread, that is not actually
accurate. That's why those quote marks, presumably.

In the sense that C++ programmers use "reference", Java objects are passed by
value, and the official word in Java is that references are passed by value
just as primitives are.

In any event, reassigning the formal parameter within a method does not change
the reference passed from the caller's point of view.

Stefan Ram provided good examples of idioms to handle the OP's need.
 
L

Lew

Andreas said:
The objects are indeed passed by reference.

When I took a practice certification exam in Java, I was marked wrong for
saying that objects are passed by reference. The fact is that objects are not
passed at all - references are, and they are passed by value.
 
A

Andreas Leitgeb

Lew said:
When I took a practice certification exam in Java, I was marked wrong for
saying that objects are passed by reference. The fact is that objects are not
passed at all - references are, and they are passed by value.

This indication of lingual hairsplitting perhaps explains, why I got
somewhat less than 100% for my SCJP (but still by far enough to pass).
Can't say for sure, since one is never told, which of the questions
were really answered wrongly.

Just as well one could say that nothing at all is passed (since methods
don't have arms or hands to pass things around), but only written to some
physical memory-location where it is then accessible to the called method...
and then we go on, that the jvm doesn't really "call" the method, because
the method doesn't have ears to hear any calling...(btw., "invoke" also has
an etymology that boils down to some form of akoustic communication.)
Really, this makes me sick.
 
P

Patricia Shanahan

Andreas said:
This indication of lingual hairsplitting perhaps explains, why I got
somewhat less than 100% for my SCJP (but still by far enough to pass).
Can't say for sure, since one is never told, which of the questions
were really answered wrongly.

Just as well one could say that nothing at all is passed (since methods
don't have arms or hands to pass things around), but only written to some
physical memory-location where it is then accessible to the called method...
and then we go on, that the jvm doesn't really "call" the method, because
the method doesn't have ears to hear any calling...(btw., "invoke" also has
an etymology that boils down to some form of akoustic communication.)
Really, this makes me sick.

I don't think this one is just hairsplitting. The "objects passed by
reference" model does not explain what happens when the actual argument
is a null reference. The actual behavior matches nicely the behavior
that predicted by the "references passed by value" model.

More generally, the "references passed by value" fits well with the
general observation that non-primitive expressions are all possibly-null
references, not objects. The actual argument is just a reference expression.

Patricia
 
A

angelochen960

Hi guys,

Thanks for all the answers, I'm kind of surprised that a simple
question got so many answers! is this statement correct:

Everything in Java are passed by value, in the case of an object, a
reference to the object is passed, which is a value too, updating the
fields in the reference does reflect the changes. anyway, maybe I
should not try to understand java in a C++ manner.

but i can't help, String is a object, so a reference should be the one
passed, and why we can not update the field in the String object? and
then where is the field of the String?


Angelo
 
D

Donkey Hot

Hi guys,

Thanks for all the answers, I'm kind of surprised that a simple
question got so many answers! is this statement correct:

Everything in Java are passed by value, in the case of an object, a
reference to the object is passed, which is a value too, updating the
fields in the reference does reflect the changes. anyway, maybe I
should not try to understand java in a C++ manner.

but i can't help, String is a object, so a reference should be the one
passed, and why we can not update the field in the String object? and
then where is the field of the String?

Yes, I was wrong in my

public void myFunc(String s) {
s = "123";
}

because that compiles exactly as

public void myFunc(String s) {
s = new String("123");
}


If the String class had a method setValue() we could write

public void myFunc(String s) {
s.setValue("123");
}

but it does not, and we can't.

Some kind of a wrapper class is needed with the methods required.
 
R

rmoldskr+usenet

Hi guys,

Thanks for all the answers, I'm kind of surprised that a simple
question got so many answers! is this statement correct:

Everything in Java are passed by value, in the case of an object, a
reference to the object is passed, which is a value too, updating the
fields in the reference does reflect the changes. anyway, maybe I
should not try to understand java in a C++ manner.

Think of it like this: Java has two different types of arguments,
fundamental values and references (similar to "smart pointers" in C++
terms). Both of these are copied by value.

Let's say you make the following two declarations:

int aNumber = 15;
String aString = "Hey!";

This will create three things in memory: an int with the value 15, a String
object with the value "Hey!" and a reference to the string object. Let's say
these are stored in memory addresses 0x1000, 0x2000 and 0x3000 respectively:

0x1000: 15
0x2000: "Hey!"
0x3000: ->0x2000

If you now make a call to a subroutine:

doStuff( aString, aNumber );

Local copies will be made of the int and of the reference, but not of the
object. Let's say these local copies are stored in 0x4000 and 0x5000:

0x1000: 15
0x2000: "Hey!"
0x3000: ->0x2000
0x4000: ->0x2000
0x5000: 15

If doStuff( ) looks like this, just before the method returns we'll have the
situation below:

private void doStuff( String aString, int aNumber ) {
aString = "Hello!";
aNumber = 20;
}

0x1000: 15
0x2000: "Hey!"
0x3000: ->0x2000
0x4000: ->0x6000
0x5000: 20
0x6000: "Hello!"

Then, once the local variables have been reclaimed, we'll be back to this:

0x1000: 15
0x2000: "Hey!"
0x3000: ->0x2000

(Well, 0x6000 will still contain the "Hello!" string until the next run of
the garbage collector, but we have no way of making use of it.)
 
R

RedGrittyBrick

(e-mail address removed) wrote:

Top-posting re-ordered - please don't top-post.
Thanks for all the answers, I'm kind of surprised that a simple
question got so many answers! is this statement correct:

Everything in Java are passed by value, in the case of an object, a
reference to the object is passed, which is a value too, updating the
fields in the reference does reflect the changes.

Its sort of correct but the language is a bit sloppy and open to
misinterpretation.

anyway, maybe I
should not try to understand java in a C++ manner.

I think you shouldn't. People who do seem to get confused.

but i can't help,

Oh dear.

String is a object,
Yes

so a reference should be the one passed,

Yes, well a copy of the reference is passed.

and why we can not update the field in the String object?

1) Strings don't have any public fields of the sort you imply.
2) Strings are immutable by definition.

Not all objects are immutable (obviously) but Strings are, by intention.

and then where is the field of the String?

This isn't a meaningful question.


Consider ...
main() {
String x = "aaa";
foo(x);
}
static void foo(String s) {
String p = s; // ONE
s = "bbb" // TWO
}

There is an object of class String, having been instantiated it exists
somewhere in memory. Within this chunk of memory is (presumably) the
UCS-2 representation of the characters "aaa".

Just before assignment TWO there are at least three references that
"point" to this object. These three references have three names (x, s
and p). We can say that variables x,s and p contain a reference to the
same object. However s is a copy of x it isn't a reference or pointer to x.

If I were writing a JVM I might have structures not entirely unlike like
this:

After assignment "ONE":

addr contents

000 "x" 122 "s" 177 "p" 127
044 3 "aaa"
122 44
127 44
177 44

After assignment "TWO":

000 "x" 122 "s" 177 "p" 127
044 3 "aaa"
122 44
127 44
177 251
251 3 "bbb"

Notice that changing what s points to has no effect on what x points to.

I expect everyone will be glad I am not writing a JVM.
 
W

Wayne

Andrea said:
Roedy is right, also a reference is passed by value.

Roedy is always right (almost). But I would state this differently:
objects are not passed at all in Java, and everything else
(including references to objects) is passed by value.

-Wayne
 
M

Mark Space

Hi,

what is the equivalent of Java approach to this C++ function:

public void myFunc(String &s) {
s = "123";
}

I'd like to define a method where several values can be returned. any
idea?


While a lot of the discussion here is pretty good, I think it missed the
fundamental point of giving the OP a simple answer.


public void myFunc( String [] sa )
{
sa[0] = "123";
}

In Java, all primitives are passed by value, as has been much discussed.
So you have to create a reference yourself, because there is is no
pass by reference available.

The most common pattern is just to use an array to pass the object
reference. The reference can then be replaced with another reference
and processed by the caller.

public static void main( String [] args )
{
String sb[] = { "456" };
myFunc( sb );
System.out.println( sb[0] );
}

It's a little hokey, but it works. Well except for the static context
..... make myFunc static for this example.

Not compiled....
 
R

Roedy Green

All objects are "passed by reference" and all primitive types have
their value copied.

The JLS is very clear on that. There is NO pass by reference in java.
Patricia argued persuasively some time ago why we should not muddle
the issue with talk of passing "objects by reference".

You can't pass objects in Java. You can in C, actually pushing the
entire object's contents to the stack.

In Java, you can pass a reference by value, however.

see http://mindprod.com/jgloss/callbyreference.html
http://mindprod.com/jgloss/callbyvalue.html
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top