Equivalent of void myRoutine in Java?

Question:
I know that in order to pass something byreference, you pass an already-created objectand let the subroutine modify the contents ofthat object. Unfortunately, the Integer, String,etc. objects don’t allow their internal values tobe changed. How can I do the equivalent ofvoid myRoutine (int *x, int *y, int *z) in Java?

Answer:
First a little background for Java newcomers:

Java methods can manipulate two types of parameters: scalars (numbers,booleans and characters) and pointers to objects (objects = arrays orclass instances). A method receives private copies of all its parameters.In the case of a pointer, this amounts to a private or local copy of apointer to a non-local object, which means modifications made inside amethod to instance variables or components of an object pointer parameterare modifications made to the corresponding non-local object. Thesemodifications can be intentional or unintentional.

The Java parameter passing mechanism can be compared to the pass-by-valueand pass-by-reference mechanisms in C++:

   void foo(Object x, scalar y) { … }   // Java method   void foo(Object &x, scalar y) { … }  // corresponding C++ function
It’s also similar to passing pointers in C (or C++) except pointer parametersmust be explicitly dereferenced in the function body, and addresses must beexplicitly passed as inputs:
 void foo(Object *x, scalar y){ … }  // bind x to &a, use *x in … 
When would a programmer intentionally modify instance variables of a non-localobject? This would be the case if the object models a mutable “real world”object, i.e. an object with internal state that can change without changingthe identity of the object. The classical example is a bank account. In thiscase its mutable internal state is its balance:
   class Account {      // …      public double balance; // should be private, see note at bottom   } 
Here’s a fragment of code that manipulates bank accountbalances:
   class Bank {      private Account[] accts = new Account[500]; // the bank’s accounts      // …      public void deposit(double amount, Account acct) {         acct.balance += amount; // will modify non-local accts[i]      }      // …   } 
A method that intentionally modifies an instance variable of a non-localobject is called a mutator.

Enough background, back to the original question. For every Java scalartype there is a corresponding Java class called the wrapper for that type.For example, the wrapper for the type int is the classInteger. Thus, everyscalar has a corresponding class instance. This gives us a choice when wedesign a method that expects a scalar input.

Should the input be a scalaror a pointer to the corresponding object wrapper? For example:

   void foo(int x) { … }  or  void foo(Integer x) { … }? 
In the first case, foo will get private copies of itsint parameters; inthe second case, foo receives pointers to its Integerparameters.

Is there a danger in the second case that the non-local Integerobject willbe unintentionally modified inside foo()? This might be aconcern, except Java regards scalars as non-mutable (i.e. stateless)objects. Indeed,this is the view most mathematicians have of scalars. (C-isms like”x = x + 1” drive mathematicians crazy!) Since scalars areregarded asnon-mutable, Java does not provide any way for programmers to modify theinternal state, i.e. the value, of an Integer object since this would beequivalent to trying to reassign the value of a constant: 5 = 5 + 1.

Nevertheless, C and C++ programmers often pass scalar pointers andscalar references to functions that modify theirparameters:

void inc(int *x) { *x = *x + 1;}  or  voidinc(int &x) { x = x + 1; }
How would this be done in Java?

First, notice that neither function makes sense if called with a constant:

   inc(5) 
(This is handled by passing a temporary variable containing 5.)

The input must be a variable or a pointer to one. That being thecase, we should think of the true input to inc as a mutablecontainer. With this in mind, we should avoid passing non-mutable Integerwrappers to mutators, and instead pass custom made mutable integercontainers:

   class IntContainer {      // …      public int value;   }
Here’s inc:
void inc(IntContainer x) { x.value = x.value + 1; }
One last note: It’s bad form to have public instance variables. Instead,provide member function mutators and accessors:
   class IntContainer {      // …      // accessor (aka selector)      public int getValue() { return value; }      // mutator      public void setValue(int val) {         value = val;      }      // …      private int value;   } 
and then:
   void inc(IntContainer x) { x.setValue(x.getValue() + 1); } 

Share the Post:
Share on facebook
Share on twitter
Share on linkedin

Overview

Recent Articles: