RTTI syntax

Bruce Eckel’s Thinking in Java Contents | Prev | Next

//: ToyTest.java
// Testing class Class
 
interface HasBatteries {}
interface Waterproof {}
interface ShootsThings {}
class Toy {
  // Comment out the following default
  // constructor to see 
  // NoSuchMethodError from (*1*)
  Toy() {}
  Toy(int i) {}
}
 
class FancyToy extends Toy
    implements HasBatteries,
      Waterproof, ShootsThings {
  FancyToy() { super(1); }
}
 
public class ToyTest {
  public static void main(String[] args) {
    Class c = null;
    try {
      c = Class.forName("FancyToy");
    } catch(ClassNotFoundException e) {}
    printInfo(c);
    Class[] faces = c.getInterfaces();
    for(int i = 0; i < faces.length; i++)
      printInfo(faces[i]);
    Class cy = c.getSuperclass();
    Object o = null;
    try {
      // Requires default constructor:
      o = cy.newInstance(); // (*1*)
    } catch(InstantiationException e) {}
      catch(IllegalAccessException e) {}
    printInfo(o.getClass());
  }
  static void printInfo(Class cc) {
    System.out.println(
      "Class name: " + cc.getName() +
      " is interface? [" +
      cc.isInterface() + "]");
  }
} ///:~ 

You
can see that
class
FancyToy

is quite complicated, since it inherits from
Toy
and
implements
the
interfaces
of
HasBatteries,
Waterproof,
and
ShootsThings.
In
main( ),
a
Class
handle is created and initialized to the
FancyToy
Class
using
forName( )
inside an appropriate
try
block.

The
newInstance( )
method of
Class
can, at first, seem like just another way to
clone( )
an object. However, you can create a new object with
newInstance( )
without
an existing object, as seen here, because there is no
Toy
object, only
cy,
which is a handle to
y’s
Class
object. This is a way to implement a “virtual constructor,” which
allows you to say “I don’t know exactly what type you are, but
create yourself properly anyway.” In the example above,
cy
is just a
Class
handle with no further type information known at compile time. And when you
create a new instance, you get back an
Object
handle. But that handle is pointing to a
Toy
object. Of course, before you can send any messages other than those accepted by
Object,
you have to investigate it a bit and do some casting. In addition, the class
that’s being created with
newInstance( )
must have a default constructor. There’s no way to use
newInstance( )
to
create objects that have non-default constructors, so this can be a bit
limiting in Java 1. However, the
reflection
API in Java 1.1

(discussed in the next section) allows you to dynamically use any constructor
in a class.

The
output from this program is:

Class name: FancyToy is interface? [false]
Class name: HasBatteries is interface? [true]
Class name: Waterproof is interface? [true]
Class name: ShootsThings is interface? [true]
Class name: Toy is interface? [false]

More by Author

Must Read