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
Christian Schnorr
  • 10,768
  • 8
  • 48
  • 83
  • Take a look [here](http://stackoverflow.com/questions/21274346/how-can-you-extend-java-to-introduce-passing-by-reference). – Sotirios Delimanolis Feb 27 '14 at 17:54
  • How about `MyClass object = doStuff()`? – JB Nizet Feb 27 '14 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. – user2864740 Feb 27 '14 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. – Christian Schnorr Feb 27 '14 at 17:57
  • 4
    Create a class containing both values as fields. And return an instance of this class. – JB Nizet Feb 27 '14 at 17:58
  • @user2864740: "There are no pointers in Java." Well, actually, all non-primitive types are reference types. And a reference is a pointer to an object. – newacct Feb 28 '14 at 07:32

5 Answers5

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.

ajb
  • 31,309
  • 3
  • 58
  • 84
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.

Brian Agnew
  • 268,207
  • 37
  • 334
  • 440
  • `doStuff()` has a different return value. Think of the function as returning two values, one directly via return and one with this hack. – Christian Schnorr Feb 27 '14 at 17:57
  • 2
    doStuff() maybe doTooMuch()? I'm sure this would be trivial to solve with a bit of context. – Ben Thurley Feb 27 '14 at 18:03
  • 1
    You have 133k reputation, please don't tell me that you can't think of a function that has multiple return values... – Christian Schnorr Feb 27 '14 at 20:11
  • @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. – Brian Agnew Feb 28 '14 at 09:52
  • @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](https://developer.apple.com/library/ios/documentation/uikit/reference/UIColor_Class/Reference/Reference.html#//apple_ref/occ/instm/UIColor/getRed:green:blue:alpha:). 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. – Christian Schnorr Mar 01 '14 at 09:25
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);
RMachnik
  • 3,598
  • 1
  • 34
  • 51
0

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.

Thomas
  • 87,414
  • 12
  • 119
  • 157
0

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

robermann
  • 1,722
  • 10
  • 19