Login | Register   
LinkedIn
Google+
Twitter
RSS Feed
Download our iPhone app
TODAY'S HEADLINES  |   ARTICLE ARCHIVE  |   FORUMS  |   TIP BANK
Browse DevX
Sign up for e-mail newsletters from DevX


Tip of the Day
Language: Java Language
Expertise: Beginner
Mar 20, 1997

Equivalent of void myRoutine in Java?

Question:
I know that in order to pass something by reference, you pass an already-created object and let the subroutine modify the contents of that object. Unfortunately, the Integer, String, etc. objects don't allow their internal values to be changed. How can I do the equivalent of void 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 or class 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 a pointer to a non-local object, which means modifications made inside a method to instance variables or components of an object pointer parameter are modifications made to the corresponding non-local object. These modifications can be intentional or unintentional.

The Java parameter passing mechanism can be compared to the pass-by-value and 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 parameters must be explicitly dereferenced in the function body, and addresses must be explicitly 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-local object? 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 changing the identity of the object. The classical example is a bank account. In this case 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 account balances:
   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-local object is called a mutator.

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

Should the input be a scalar or 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 its int parameters; in the second case, foo receives pointers to its Integer parameters.

Is there a danger in the second case that the non-local Integer object will be unintentionally modified inside foo()? This might be a concern, 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 are regarded as non-mutable, Java does not provide any way for programmers to modify the internal state, i.e. the value, of an Integer object since this would be equivalent to trying to reassign the value of a constant: 5 = 5 + 1.

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

void inc(int *x) { *x = *x + 1;}  or  void
inc(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 the case, we should think of the true input to inc as a mutable container. With this in mind, we should avoid passing non-mutable Integer wrappers to mutators, and instead pass custom made mutable integer containers:

   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); }
 
DevX Pro
 
Comment and Contribute

 

 

 

 

 


(Maximum characters: 1200). You have 1200 characters left.

 

 

Sitemap
Thanks for your registration, follow us on our social networks to keep up-to-date