Returning primitives by reference

B

Bill Medland

I just thought I'd check before I make a real fool of myself. Am I right in
deducing that in Java we can't really return multiple primitives from a
method; we need either to cast to objects or else package them in a class?

I am porting an API from C++/COM and from C#/.NET to Java.

The existing API contains a load of functions that return a boolean
success/failure (or sometimes an integer status) and return the information
through pointers in the argument list.

For example (pseudo-language) bool getFiscalQuarter(string y, int p, out int
quarter) returns true if it can be figured out and false otherwise.

My understanding is that Java does not support referencing like this. Is
that correct?

(The solutions I know of are:
1. Return the quarter, throwing an exception if it cannot be figured out
2. Take a java.lang.Integer as an argument and modify it
)
 
O

Oliver Wong

Bill Medland said:
I just thought I'd check before I make a real fool of myself. Am I right
in
deducing that in Java we can't really return multiple primitives from a
method; we need either to cast to objects or else package them in a class?

I am porting an API from C++/COM and from C#/.NET to Java.

The existing API contains a load of functions that return a boolean
success/failure (or sometimes an integer status) and return the
information
through pointers in the argument list.

For example (pseudo-language) bool getFiscalQuarter(string y, int p, out
int
quarter) returns true if it can be figured out and false otherwise.

My understanding is that Java does not support referencing like this. Is
that correct?

Correct.
(The solutions I know of are:
1. Return the quarter, throwing an exception if it cannot be figured out

Good idea.
2. Take a java.lang.Integer as an argument and modify it

This won't work. Integer is immutable.

- Oliver
 
S

Steve W. Jackson

Bill Medland said:
I just thought I'd check before I make a real fool of myself. Am I right in
deducing that in Java we can't really return multiple primitives from a
method; we need either to cast to objects or else package them in a class?

I am porting an API from C++/COM and from C#/.NET to Java.

The existing API contains a load of functions that return a boolean
success/failure (or sometimes an integer status) and return the information
through pointers in the argument list.

For example (pseudo-language) bool getFiscalQuarter(string y, int p, out int
quarter) returns true if it can be figured out and false otherwise.

My understanding is that Java does not support referencing like this. Is
that correct?

(The solutions I know of are:
1. Return the quarter, throwing an exception if it cannot be figured out
2. Take a java.lang.Integer as an argument and modify it
)

You're partially correct.

Java, like C/C++, can only return at most one value from a method call.
It is possible for parameters that are object references to be passed
and then used to update fields contained therein.

But the idea you describe whereby a parameter of type Integer is passed
in for your "quarter" isn't going to work because the Integer class in
Java is immutable. You cannot change an Integer, Double, Boolean, Float
or String. The variable you receive for one of these refers to the
location where the original object is located, but there aren't any
methods to change it. You could only replace your local reference with
a new Integer object, which wouldn't do any good to the caller.

Instead, you could pass an object of some other class (say Quarter) and
have mutable fields in it, with methods that can change their values.

= Steve =
 
E

Eric Sosman

Bill Medland wrote On 07/20/06 16:21,:
I just thought I'd check before I make a real fool of myself. Am I right in
deducing that in Java we can't really return multiple primitives from a
method; we need either to cast to objects or else package them in a class?

You're right. It's nothing to do with primitives as such,
though, it's just that a Java method can return only one value
(or none, for a void method). That single value can be a
primitive, or it can be a reference.
I am porting an API from C++/COM and from C#/.NET to Java.

The existing API contains a load of functions that return a boolean
success/failure (or sometimes an integer status) and return the information
through pointers in the argument list.

For example (pseudo-language) bool getFiscalQuarter(string y, int p, out int
quarter) returns true if it can be figured out and false otherwise.

My understanding is that Java does not support referencing like this. Is
that correct?

Yes; method arguments are passed by value. A method argument
can, of course, be a reference to a mutable object instance --
but there is no way to form a "reference" to a primitive.
(The solutions I know of are:
1. Return the quarter, throwing an exception if it cannot be figured out
2. Take a java.lang.Integer as an argument and modify it
)

#1 works, but is a poor choice unless the failures are
truly "exceptional." The topic of (ab)using exceptions for
"routine" control flow has been discussed many times; see
the archives.

#2 almost works, but you'll find there's no way to modify
an Integer! What you need is a ModifiableInteger object that
acts very much like an Integer but has a setValue(int) method.

Another approach would be to set up an enumeration with
the elements Q1, Q2, Q3, Q4. You'd return one of them if
successful, or null if unsuccessful. The Q1/2/3/4 object
instances could, of course, have methods of their own to
retrieve a simple int index number, start and end dates, and
whatever else is useful.

The above is essentially the "special value" approach,
where you return one of many possible legitimate values for
a successful computation or an easily-identified illegitimate
value to indicate failure. (If there are plenty of impossible
values, you can even distinguish between different failure
causes.) If you've got a situation where the legitimate values
cover the entire range of int, say, one dodge is to return the
value as an Integer rather than as an int and return null to
indicate failure. For doubles and floats, a NaN can sometimes
serve this role.

However, it must be admitted that using a special value
is really a hack: It's an attempt to cram the two unrelated
notions of "status" and "value" through a single channel.
Some of the Y2K problems stemmed from channel overloads of
this kind (e.g., using a special value like 00 or 99 to mean
"year not known"). Maintaining independent channels (perhaps
by returning an object that carries both value and status) is
somewhat more verbose, but vastly more powerful.
 
C

Chris Uppal

Bill said:
I just thought I'd check before I make a real fool of myself. Am I right
in deducing that in Java we can't really return multiple primitives from a
method; we need either to cast to objects or else package them in a class?

I am porting an API from C++/COM and from C#/.NET to Java.

You are correct (as the others have already said). It sounds as if the
existing API is fairly clumsily designed; C++/COM will let you get away with a
very low-level API design; Java will not.

So you should resign yourself to redesigning the API. Don't just try to kludge
up a selection of arbitrary hacks to try to emulate the C++ code. Look for
where there /should/ have been objects in the original design, and provide them
explicitly this time around.

-- chris
 
S

Stefan Ram

Bill Medland said:
I just thought I'd check before I make a real fool of myself.
Am I right in deducing that in Java we can't really return
multiple primitives from a method; we need either to cast to
objects or else package them in a class?

Here is how I "return" two ints from a method,
no references are needed:

interface AcceptIntInt { void accept( int x, int y ); }

class Server
{ static java.util.Random rand = new java.util.Random();
static void getPair( final AcceptIntInt acceptIntInt )
{ acceptIntInt.accept( rand.nextInt( 11 ), rand.nextInt( 21 )); }}

public class Main
{ public static void main( final java.lang.String[] args )
{ Server.getPair( new AcceptIntInt()
{ public void accept( final int x, final int y )
{ java.lang.System.out.println( x + ", " + y ); }}); }}

8, 12
 
T

Tony Morris

I just thought I'd check before I make a real fool of myself. Am I right in
deducing that in Java we can't really return multiple primitives from a
method; we need either to cast to objects or else package them in a class?

You cannot return more than one value with the exception of signals (aka
exceptions), which are an alternative path of execution given a different
return value (and a source of amusement if you care to observe the good
ol' checked vs unchecked exception debate from the sideline :)).

You refer to the class as the solution, but instead, it is contract that
is to be considered "first-class" - despite the unfortunate atrocities of
much literature. Contracts are written in Java using the interface
keyword. You could simply return this:
interface TwoInts {
int getX();
int getY();
}

Another alternative does away with return values altogether (since
imperative programming is for monkeys after all :)) You could pass a
"quasi-closure" for each value that you want returned. Certainly, this is
*always* preferred to using exceptions/signals (which contain many
inherent flaws, hence the amusement of the aforementioned debate which
relies on these flaws), but can lead to extremely verbose code - since you
are forced to never leak scope in a local context, as well as the type +
method + the actual code within the "quasi-closure". There is some
decision to be made based on these apparent opposing benefits. I use the
term "quasi-closure" conservatively since Java has no such thing as a
closure and a purist (such as myself) would argue that the so-called
"quasi-closure" is not even a close resemblance.

To point out the scope leak that quite often many imperative programs
overlook:
int x = 42;
method(x);
int y = 43;
method(y);
Of the 4 lines above, the local declaration 'x' "leaks scope" beyond line
2. This is typically overlooked, since Java is all about producing as much
scope leak as possible in hope of producing something resembling software
within it, and scope leak within a local context is generally less
adversely consequential than many alternatives. Nevertheless, the above
imperative code written using the method that I refer to would imply that
this scope leak disappears (since it must).
 
O

Oliver Wong

Tony Morris said:
To point out the scope leak that quite often many imperative programs
overlook:
int x = 42;
method(x);
int y = 43;
method(y);
Of the 4 lines above, the local declaration 'x' "leaks scope" beyond line
2. This is typically overlooked, since Java is all about producing as much
scope leak as possible in hope of producing something resembling software
within it, and scope leak within a local context is generally less
adversely consequential than many alternatives. Nevertheless, the above
imperative code written using the method that I refer to would imply that
this scope leak disappears (since it must).

You could write it without "scope leak" like this:

{
int x = 42;
method(x);
}
{
int y = 43;
method(y);
}

- Oliver
 

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

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,230
Members
46,818
Latest member
Brigette36

Latest Threads

Top