Passing handles around | CodeGuru

Passing handles around

Bruce Eckel’s Thinking in Java Contents | Prev | Next When you pass a handle into a method, you’re still pointing to the same object. A simple experiment demonstrates this: (See page 97 if you have trouble executing this program.) //: PassHandles.java // Passing handles around package c12;   public class PassHandles { static void […]

Written By
CodeGuru Staff
CodeGuru Staff
Mar 1, 2001
3 minute read
CodeGuru content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More

When


you pass a

handle
into a method, you’re still pointing to the same object. A simple
experiment demonstrates this: (See page
97
if you have trouble executing this program.)
//: PassHandles.java
// Passing handles around
package c12;
 
public class PassHandles {
  static void f(PassHandles h) {
    System.out.println("h inside f(): " + h);
  }
  public static void main(String[] args) {
    PassHandles p = new PassHandles();
    System.out.println("p inside main(): " + p);
    f(p);
  }
} ///:~ 

The


method


toString( )

is automatically invoked in the print statements, and


PassHandles

inherits directly from


Object

with no redefinition of


toString( )

.


Thus,


Object

’s


version of


toString( )

is


used, which prints out the class of the object followed by the address where


that object is located (not the handle, but the actual object storage). The


output looks like this:

p inside main(): PassHandles@1653748
h inside f(): PassHandles@1653748

You


can see that both


p

and


h

refer to the same object. This is far more efficient than duplicating a new


PassHandles

object just so that you can send an argument to a method. But it brings up an


important issue.


Aliasing

Aliasing


means that more than one handle is tied to the same object, as in the above


example. The problem with aliasing occurs when someone


writes

to that object. If the owners of the other handles aren’t expecting that


object to change, they’ll be surprised. This can be demonstrated with a


simple example:

//: Alias1.java
// Aliasing two handles to one object
 
public class Alias1 {
  int i;
  Alias1(int ii) { i = ii; }
  public static void main(String[] args) {
    Alias1 x = new Alias1(7);
    Alias1 y = x; // Assign the handle
    System.out.println("x: " + x.i);
    System.out.println("y: " + y.i);
    System.out.println("Incrementing x");
    x.i++;
    System.out.println("x: " + x.i);
    System.out.println("y: " + y.i);
  }
} ///:~ 

In


the line:

Alias1
y = x; // Assign the handle

a


new


Alias1

handle is created, but instead of being assigned to a fresh object created with


new

,


it’s assigned to an existing handle. So the contents of handle


x

,


which is the address of the object


x

is pointing to, is assigned to


y

,


and thus both


x

and


y

are attached to the same object. So when


x

’s


i

is incremented in the statement:

x.i++; y

’s


i

will


be affected as well. This can be seen in the output:

x: 7
y: 7
Incrementing x
x: 8
y: 8

One


good solution in this case is to simply not do it: don’t consciously


alias more than one handle to an object at the same scope. Your code will be


much easier to understand and debug. However, when you’re passing a


handle in as an argument – which is the way Java is supposed to work


– you automatically alias because the local handle that’s created


can modify the “outside object” (the object that was created


outside the scope of the method). Here’s an example:

//: Alias2.java
// Method calls implicitly alias their
// arguments.
 
public class Alias2 {
  int i;
  Alias2(int ii) { i = ii; }
  static void f(Alias2 handle) {
    handle.i++;
  }
  public static void main(String[] args) {
    Alias2 x = new Alias2(7);
    System.out.println("x: " + x.i);
    System.out.println("Calling f(x)");
    f(x);
    System.out.println("x: " + x.i);
  }
} ///:~ 

The


output is:

x: 7
Calling f(x)
x: 8

The


method is changing its argument, the outside object. When this kind of


situation arises, you must decide whether it makes sense, whether the user


expects it, and whether it’s going to cause problems.

In


general, you call a method in order to produce a return value and/or a change


of state in the object


that
the method is called for

.


(A method is how you “send a message” to that object.) It’s


much less common to call a method in order to manipulate its arguments; this is


referred to as “calling a method for its

side
effects
.”
Thus, when you create a method that modifies its arguments the user must be
clearly instructed and warned about the use of that method and its potential
surprises. Because of the confusion and pitfalls, it’s much better to
avoid changing the argument.

If


you need to modify an argument during a method call and you don’t intend


to modify the outside argument, then you should protect that argument by making


a copy inside your method. That’s the subject of much of this chapter.


Contents

|

Prev

|

Next
CodeGuru Logo

CodeGuru covers topics related to Microsoft-related software development, mobile development, database management, and web application programming. In addition to tutorials and how-tos that teach programmers how to code in Microsoft-related languages and frameworks like C# and .Net, we also publish articles on software development tools, the latest in developer news, and advice for project managers. Cloud services such as Microsoft Azure and database options including SQL Server and MSSQL are also frequently covered.

Property of TechnologyAdvice. © 2026 TechnologyAdvice. All Rights Reserved

Advertiser Disclosure: Some of the products that appear on this site are from companies from which TechnologyAdvice receives compensation. This compensation may impact how and where products appear on this site including, for example, the order in which they appear. TechnologyAdvice does not include all companies or all types of products available in the marketplace.