Java in Notes/Domino Explained: Casting 101


To discuss and understand casting you must know that when you instantiate an object in Java you create an object on the heap and a reference to the object on the stack. In your Java agents you only have direct access to what’s on the stack which means that what you manipulate in your code are the references. Since you do not work with the objects on the heap directly the reference on the stack must tell the JVM which type of object is at the memory location pointed to on the heap.

Casting means taking an existing object reference and making it of another type. When most Java developers talk about casting they refer to “casting objects” which strictly speaking is wrong. It is however one of those things you learn to live with… 🙂

A simple example

As you might know every class in Java ultimatively inherits from java.lang.Object which means that a java.lang.Object reference can point to anything (much like a Variant in LotusScript). This means that you can always cast an object to java.lang.Object since it is a more generic type.

However you cannot store a java.lang.Object reference in a java.lang.String reference without casting since String is more specific than Object. As you can see I have to cast the obj reference to a String reference in line 3. If I don’t the code wont compile.

String sample1 = "This is my string..."; // create a String
Object obj     = sample1;                // store String in java.Object reference
String sample2 = (String)obj;            // we must cast to store an Object in a String
                                         // reference

To sum up you need to cast when refering to an object with a more specific reference than the current reference.

When casting references you may encounter the java.lang.ClassCastException which is an unchecked exception. This exception is the way the JVM can signal that you are doing an illegal cast for example casting a lotus.domino.Document to a lotus.domino.Database.

Knowing when it’s okay to cast

So how do you check if a cast is legal? Well apart from knowing which references you are dealing with you can use the instanceof keyword. The below example checks that the object really does inherit from lotus.domino.RichTextItem before casting:

// declarations
RichTextItem rt = null;
Item item = null;

// get document
Document doc = db.getDocumentByUnid("<some unid>");

// loop all items and put them into an ArrayList
Vector items = doc.getItems();
for (int i=0; i<items.size(); i++) {
   // get next element from the Vector (returns java.lang.Object)
   Object obj = items.elementAt(i);

   // is the item a RichTextItem?
   if (obj instanceof RichTextItem) {
      // yes it is - cast it as such
      rt = (RichTextItem)obj;
   } else {
      // nope - cast it as an Item
      item = (Item)obj;
   }
}

The above example is equivalent to the below code exept that I use the ClassCastException to find out that the cast is invalid.

// declarations
RichTextItem rt = null;
Item item = null;

// get document
Document doc = db.getDocumentByUnid("<some unid>");

// loop all items and put them into an ArrayList
Vector items = doc.getItems();
for (int i=0; i<items.size(); i++) {
   // get next element from the Vector (returns java.lang.Object)
   Object obj = items.elementAt(i);

   try {
      // try to cast as RichTextItem
      rt = (RichTextItem)obj;

      // coming here means that the item is a RichTextItem
      ...
   } catch (ClassCastException e) {
      // not a RichTextItem - cast it as an Item
      item = (Item)obj);
   }
}