RTTI considered harmful? | CodeGuru

RTTI considered harmful?

Bruce Eckel’s Thinking in Java Contents | Prev | Next Various designs in this chapter attempt to remove RTTI, which might give you the impression that it’s “considered harmful” (the condemnation used for poor, ill-fated goto, which was thus never put into Java). This isn’t true; it is the misuse of RTTI that is the […]

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

Various


designs in this chapter attempt to remove RTTI, which might give you the


impression that it’s “considered harmful” (the condemnation


used for poor, ill-fated


goto

,


which was thus never put into Java). This isn’t true; it is the

misuse
of RTTI that is the problem. The reason our designs removed RTTI is because the
misapplication of that feature prevented
extensibility,
while the stated goal was to be able to add a new type to the system with as
little impact on surrounding code as possible. Since RTTI is often misused by
having it look for every single type in your system, it causes code to be
non-extensible: when you add a new type, you have to go hunting for all the
code in which RTTI is used, and if you miss any you won’t get help from
the compiler.

However,


RTTI doesn’t automatically create non-extensible code. Let’s


revisit the trash recycler once more. This time, a new tool will be introduced,


which I call a


TypeMap

.


It contains a


Hashtable

that holds


Vector

s,


but the interface is simple: you can


add( )

a new object, and you can


get( )

a


Vector

containing all the objects of a particular type. The keys for the contained


Hashtable

are the types in the associated


Vector

.


The beauty of this design (suggested by Larry O’Brien) is that the


TypeMap

dynamically adds a new pair whenever it encounters a new type, so whenever you


add a new type to the system (even if you add the new type at run-time), it


adapts.

Our


example will again build on the structure of the


Trash

types in


package
c16.Trash

(and the


Trash.dat

file used there can be used here without change):

//: DynaTrash.java 
// Using a Hashtable of Vectors and RTTI
// to automatically sort trash into
// vectors. This solution, despite the
// use of RTTI, is extensible.
package c16.dynatrash;
import c16.trash.*;
import java.util.*;
 
// Generic TypeMap works in any situation:
class TypeMap {
  private Hashtable t = new Hashtable();
  public void add(Object o) {
    Class type = o.getClass();
    if(t.containsKey(type))
      ((Vector)t.get(type)).addElement(o);
    else {
      Vector v = new Vector();
      v.addElement(o);
      t.put(type,v);
    }
  }
  public Vector get(Class type) {
    return (Vector)t.get(type);
  }
  public Enumeration keys() { return t.keys(); }
  // Returns handle to adapter class to allow
  // callbacks from ParseTrash.fillBin():
  public Fillable filler() {
    // Anonymous inner class:
    return new Fillable() {
      public void addTrash(Trash t) { add(t); }
    };
  }
}
 
public class DynaTrash {
  public static void main(String[] args) {
    TypeMap bin = new TypeMap();
    ParseTrash.fillBin("Trash.dat",bin.filler());
    Enumeration keys = bin.keys();
    while(keys.hasMoreElements())
      Trash.sumValue(
        bin.get((Class)keys.nextElement()));
  }
} ///:~ 

Although


powerful, the definition for


TypeMap

is simple. It contains a


Hashtable

,


and the


add( )

method does most of the work. When you


add( )

a new object, the handle for the


Class

object for that type is extracted. This is used as a key to determine whether a


Vector

holding objects of that type is already present in the


Hashtable

.


If so, that


Vector

is extracted and the object is added to the


Vector

.


If not, the


Class

object and a new


Vector

are added as a key-value pair.

You


can get an


Enumeration

of all the


Class

objects from


keys( )

,


and use each


Class

object to fetch the corresponding


Vector

with


get( )

.


And that’s all there is to it.

The


filler( )

method is interesting because it takes advantage of the design of


ParseTrash.fillBin( )

,


which doesn’t just try to fill a


Vector

but instead anything that implements the


Fillable

interface with its


addTrash( )

method. All


filler( )

needs to do is to return a handle to an


interface

that implements


Fillable

,


and then this handle can be used as an argument to


fillBin( )

like this:

ParseTrash.fillBin("Trash.dat",
bin.filler());

To


produce this handle, an

anonymous
inner class

(described in Chapter 7) is used. You never need a named class to implement
Fillable,
you just need a handle to an object of that class, thus this is an appropriate
use of anonymous inner classes.

An


interesting thing about this design is that even though it wasn’t created


to handle the sorting,


fillBin( )

is performing a sort every time it inserts a


Trash

object into


bin

.

Much


of


class
DynaTrash

should be familiar from the previous examples. This time, instead of placing


the new


Trash

objects into a


bin

of type


Vector

,


the


bin

is of type


TypeMap

,


so when the trash is thrown into


bin

it’s immediately sorted by


TypeMap

’s


internal sorting mechanism. Stepping through the


TypeMap

and operating on each individual


Vector

becomes a simple matter:

    Enumeration keys = bin.keys();
    while(keys.hasMoreElements())
      Trash.sumValue(
        bin.get((Class)keys.nextElement()));

As


you can see, adding a new type to the system won’t affect this code at


all, nor the code in


TypeMap

.


This is certainly the smallest solution to the problem, and arguably the most


elegant as well. It does rely heavily on RTTI, but notice that each key-value


pair in the


Hashtable

is looking for only one type. In addition, there’s no way you can


“forget” to add the proper code to this system when you add a new


type, since there isn’t any code you need to add.


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.