6

I need to return/update a boolean while returning a list of stuff from a method. Java can't return tuples and I didn’t want to make a separate class for this, so figured I would pass the bool as an out param. That’s what our C++ client does, passes bool by reference. That would work for a normal class since java sort of has pass-by-ref for objects (see Is Java "pass-by-reference" or "pass-by-value"? for a good discussion of this). But the “Wrapper” classes like Boolean store their primitive value as immutable, so it can't be updated in this way.

Using a boolean array (with one entry) seems hokey but is perhaps the simplest thing that works. Alternatively, could return the boolean and pass the created list back as an out param rather than as the return [but then the java client deviates from the C++, and it's best if they keep mostly the same approach- FYI need this in C# too.]

Community
  • 1
  • 1
Cincinnati Joe
  • 2,077
  • 6
  • 23
  • 32

6 Answers6

14

No, Java doesn't have pass-by-ref for objects; it has "pass reference by value" which isn't the same thing.

You definitely can't pass anything as an "out" parameter or by reference in Java - although you could in C#.

Could you encapsulate the "Boolean plus list" into another type? Are they actually related? Using a boolean array is definitely pretty ugly. You could write a MutableBoolean wrapper type - but again, that's pretty ugly. Normally I'd say that returning two things suggests the method should be split up, but when one of them is a Boolean it can be fairly reasonable - like int.TryParse etc from C#.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • @Jon - Java passes objects by ref and primitives by value. That's on the SCJP, i'm not sure what you mean by "Pass reference by value". If you pass an object as a parameter, modify the object and exit out, the object is changed. No "Copy" of the actual object exists. – Mech Feb 08 '10 at 19:48
  • Thanks. Yeah, I know java's terminology is messy, that's why I said "java sort of has pass-by-ref for objects (see question 40480 "Is Java pass by reference?" for a good discussion of this)." – Cincinnati Joe Feb 08 '10 at 19:55
  • 6
    @Mech Software - No - that's not on the SCJP exam - because it's wrong. http://bobcat.webappcabaret.net/javachina/faq/07.htm#pas_Q5 – Nate Feb 08 '10 at 20:52
  • 5
    @Mech: When did I say that the *object* is copied? The *reference* is copied. The *reference* is passed by value. You never actually pass an object - you pass a reference. And @Cincinnati Joe - it doesn't need to be messy at all. "Pass a reference by value" isn't messy or inaccurate. – Jon Skeet Feb 08 '10 at 23:40
  • Calling them "references" was a bad move IMHO. They could have called them "pointers", "object IDs", "handles" or one of a million other things that didn't mean something completely different in C++. – finnw Feb 09 '10 at 23:21
  • 1
    @finnw: "pointer" would suggest it meant a physical address in memory, which it certainly doesn't have to. "Handle" would be somewhat better, although it has a slightly different meaning in Windows. "Object ID" might not be too bad. Really "reference" isn't too bad once you've got it, and it's pretty simple to get it. – Jon Skeet Feb 09 '10 at 23:23
  • 1
    @finnw: "reference" is a generic term for things like pointers ( http://en.wikipedia.org/wiki/Reference_%28computer_science%29 ). So it is a perfectly reasonable term. I don't think that what C++ calls references is necessarily a very standard use of the term, but since a lot of people come from C++, they get stuck into this meaning of "reference". – newacct Apr 26 '12 at 17:31
8

As you say, The Boolen wrapper class is immutable, so you cannot use it to receive your output variable.

Passing in a new list to receive the list result and returning the boolean would sound most natural to me, but you have a good reason; keeping the interface roughly the same over multiple implementations.

You could solve this problem by creating your own mutable Boolean and passing a reference to it, something like:

public class Example {
    public class BooleanResult {
        private boolean result;

        public void setResult(boolean value) { result = value; }
        public boolean getResult() { return result; }
    }

    // ....
    public List doSomething(BooleanResult out) {
        List list;
        boolean result;

        // ...

        out.setResult(result);

        return list;
    }
}

and use it like:

Example.BooleanResult out = new Example.BooleanResult();

List list = example.doSomething(out);

boolean result = out.getResult();
rsp
  • 23,135
  • 6
  • 55
  • 69
  • Yes, thanks for fleshing this out (Jon had also mentioned it in his answer). I think this is what we're going with since it mostly closely matches our C++ version. – Cincinnati Joe Feb 10 '10 at 21:42
4

I need to return/update a boolean while returning a list of stuff from a method. Java can't return tuples and I didn’t want to make a separate class for this

I've encountered the same problem, and the best solution IMHO is usually:

Just forget your worries, and make a separate class.

I used to be hesitant about this, but classes are meant for encapsulating values, so go ahead and do it.

Chances are, once your function returns an instance of a custom class, you will find that there is additional functionality that fits well into that class, or other methods that could use the class as a parameter or return value, and soon the class will be fairly useful :-).

If you really don't want to do this, you can always stuff everything into a java.util.List or a java.util.Map and return that. But that's really ugly :-( I've done that as well, and come to regret it. It may seem simple at first, but as the code evolves and grows, readability suffers (was that a List of Integer, then Double, or vice versa?). Classes are much more helpful.

Note: If you feel a top-level regular class is overkill, you can use a nested class, which is nice for classes for "local use" only.

sleske
  • 81,358
  • 34
  • 189
  • 227
  • I happened to look at my notes from the recent CodeMash developer conference and recalled that this situation came up in a short presentation by Dick Wall of the Java Posse. He was speaking about Scala and said that it supports tuples for return types (he mentioned the controversial desire to add them to Java: http://stackoverflow.com/questions/457775/does-java-need-tuples). He said that in Java if you define a new "struct" class to return multiple things that you'd have to fully implement it with equals and hashcode methods and should test it - overhead for such a simple thing. – Cincinnati Joe Feb 10 '10 at 21:18
  • @Cincinnati Joe: Interesting point, thank you. As to "fully implement with equals etc.": I'd somewhat disagree. It's perfectly acceptable not to implement(override) those. You just need to remember that you should not blindly use equals() / hashcode() on a class without checking that they properly implement it. But that's a different can of worms... – sleske Feb 10 '10 at 22:31
2

You cannot use any of the primitive types as an 'out' parameter in Java. That's just not going to happen any time.

You also can't use any of the object versions, such as Boolean, Integer, Float, Double, etc, as 'out' parameters as they are immutable. What you can do is either write your own class or use something like MutableBoolean in commons-lang (http://commons.apache.org/proper/commons-lang/javadocs/api-3.1/org/apache/commons/lang3/mutable/MutableBoolean.html).

For example:

public void setTrue(MutableBoolean b) {
    b.setValue(Boolean.TRUE);
}
Barney Govan
  • 644
  • 4
  • 5
1

What I've done to return multiple values is to change the return type to return an object array. The [0] could be the bool and [1] could be the list.

The downside is that the caller must know to cast the returned objects appropriately from the object array, and the compiler can't check for you.

Edit: Here is a SO answer for returning a pair of values from Java.

Community
  • 1
  • 1
aaaa bbbb
  • 3,003
  • 2
  • 23
  • 23
  • I like the pair idea - a coworker noted that Google Collections has a Pair, but it appears it's not in their 1.0 release. – Cincinnati Joe Feb 09 '10 at 12:56
  • According to this Google Collections does *not* have a Pair class yet: http://code.google.com/p/guava-libraries/issues/detail?id=203 – finnw Feb 09 '10 at 23:13
0

As rsp and many others have mentioned, it is immutable. However, there is a boolean variation called AtomicBoolean that was introduced as part of the java.util.concurrent.atomic package in Java version 1.5. If you do not want to create classes for handling such trivial issues, AtomicBoolean is the way to go. Check it out. Run the following code to see for yourself.

public static void main(String[] args) {
    AtomicBoolean value = new AtomicBoolean(false);
    System.out.println(value); // Prints false
    someMethod(value);
    System.out.println(value); // Prints true
}

void someMethod(AtomicBoolean a) {
    a.set(true);
}
Srikanth
  • 2,014
  • 19
  • 22
  • -1 because you will have an overhead, small as it may, for the locking mechanism the Atomic parameters are implementing. they should be used to overcome concurrent issues. The Mutable parameters are a better suite for this case. – Roee Gavirel Jun 01 '16 at 15:12