devxlogo

Equivalent of void myRoutine in Java?

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.
See also  The Importance of Red Teaming in Modern Cyber Defense Strategies

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); } 

devxblackblue

About Our Editorial Process

At DevX, we’re dedicated to tech entrepreneurship. Our team closely follows industry shifts, new products, AI breakthroughs, technology trends, and funding announcements. Articles undergo thorough editing to ensure accuracy and clarity, reflecting DevX’s style and supporting entrepreneurs in the tech sphere.

See our full editorial policy.

About Our Journalist