Re: pass by reference
"angelochen960@gmail.com" <angelochen960@gmail.com> writes:
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.