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++ functionIt’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:
(This is handled by passing a temporary variable containing 5.)inc(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); }
Charlie has over a decade of experience in website administration and technology management. As the site admin, he oversees all technical aspects of running a high-traffic online platform, ensuring optimal performance, security, and user experience.




















