2

What I want to achieve is something like this:

MyClass object = null;
doStuff(&object);

// `object` can now be non-null

What I'm currently doing is this, but I think there must be a better way to achieve this behavior in Java:

MyClassPointer pointer = new MyClassPointer(null);
// pointer.object is null
doStuff(pointer);

// pointer.object can now be non-null
6
  • Take a look here. Commented Feb 27, 2014 at 17:54
  • How about MyClass object = doStuff()? Commented Feb 27, 2014 at 17:54
  • There are no pointers in Java. The only way to achieve some form of "out" or "by ref" calling semantics is to mutate an object that is supplied as an argument - as is shown in the latter case. I would recommend making doStuff simply return a useful (compound) value. Commented Feb 27, 2014 at 17:57
  • 1
    doStuff() has a different return value. Think of the function as returning two values, one directly via return and one with this hack. Commented Feb 27, 2014 at 17:57
  • 4
    Create a class containing both values as fields. And return an instance of this class. Commented Feb 27, 2014 at 17:58

5 Answers 5

2

If you really want doStuff to return two values: There may well be a better way to design this. Nevertheless, if you've decided that having doStuff return two values is really the best design, it can be done with a simple helper class:

static class MyClassAndBoolean {
    public MyClass obj;
    public boolean b;
    public MyClassAndBoolean(MyClass obj, boolean b) { this.obj = obj; this.b = b; }
}

and then change doStuff's return type to MyClassAndBoolean. This is one of the very few cases where I think public fields in a class are OK. Since you're defining a simple class just to use as a function result, rather than representing a coherent concept, the usual concerns about defining accessors instead of exposing fields, etc., don't really apply. (P.S. I just guessed at boolean for the other type, but it can be anything, of course.)

Another workaround:

MyClass[] obj = new MyClass[1];
result = doStuff(obj);

Change doStuff's parameter type to MyClass[], and have it stuff the new object into parameter[0]. I do see this idiom used in some of the Java and Android library methods.

Sign up to request clarification or add additional context in comments.

Comments

1

Why not simply:

MyClass object = doStuff();

which is much more intuitive IMHO. Otherwise you have to pass a reference (not pointer!) to a container object to your method, as you've identified. That's not a common pattern in the Java world.

5 Comments

doStuff() has a different return value. Think of the function as returning two values, one directly via return and one with this hack.
doStuff() maybe doTooMuch()? I'm sure this would be trivial to solve with a bit of context.
You have 133k reputation, please don't tell me that you can't think of a function that has multiple return values...
@Jenox. Thank you for noticing my reputation score (I don't like to brag). I would suggest that a method returning two values is not particularly good design. Returning a tuple is an option, but if the two values are related I'd prefer an object. If not related then I think the method is doing two different things.
@BrianAgnew Oh lol, I didn't even notice that the first comment wasnt't yours. I agree that this design pattern isn't optimal, but sometimes it's simply easier to use. Example by Apple. In my case it's a recursive function that evaluates the state of a game (therefore returning a double) after multiple possible move, and shall save/return the best move only on the top level of the recursion.
1

No, there is no better way since in Java you don't have pointers the way you have them in C++.

In Java references (much like pointers in C++) can't be directly accessed and are always passed by value. Thus you can't change the value of a reference within a method.

Comments

0

As far as I know java language it is the only way to do that. But you can simply implement method into your class. And in your method also there is possibility to return your object.

public MyObject myFunction(){
//do stufff...
return new MyObject();
}
MybObject object = myFucntion();

Or you can do it in your way. Also using Reflection you can invoke your method.

Method method = foo.getClass().getMethod("doSomething", null);
method.invoke(foo, null);

Comments

0

Use the Visitor pattern, your MyClass being what have to be 'visited' by dostuff

2 Comments

This has nothing to do with "visitor pattern".
If it has nothing to do, well it could have: what if it is passing a reference just to collect some data inside doStuff?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.