Search code examples
javac++pass-by-referencepass-by-valuecommand-pattern

How can I use the Command Pattern in Java like I do in C++?


I was working on a game recently in C++ where I implemented the Command Pattern to manage keyboard input to control a spaceship. When instantiating all the commands, I'd pass the spaceship pointer to each constructor so all commands were working with the same spaceship object.

This pattern made sense in C++ because you can pass by reference, but in Java everything is pass-by-value. If I tried to implement the same thing in Java, how would I have each command pointing to the same object?

In all the examples I've seen of the Command Pattern used in Java it makes no difference whether the member variables of each Command are copies or references.


Solution

  • Java does pass by value in all cases, however all 'non-primitive' types exist as references, so for types like String, List or Spaceship you're actually passing a reference around - the pass by value is because you're passing the reference by value. Which is a pretty confusing way of expressing it, I always felt.

    Anyway, the upshot of it is that if you have a (hugely simplified) Command class

    public class Command {
        private Spaceship spaceship;
        public Command(Spaceship ship) {
            spaceship = ship;
        }
    }
    

    And then you do this:

    Spaceship ship = new Spaceship();
    List<Command> ships = new List<Command>();
    for (int i = 0; i < 40; i++) {
        ships.add(new Command(ship));
    }
    

    then every single one of those Command objects has a reference to the same Spaceship object. Passing the reference by value does not cause a copy of the Spaceship object that the reference points to. However, if you were passing ints around, you would indeed be passing copies.

    Just remember the distinction between primitive types like int, and object types like String and you'll be fine. It's helpful to remember that primitive type names begin with a lowercase letter (and can never be user-defined), while object types begin with a capital letter. All user-defined types are object types.