dcsimg

RTTI syntax

WEBINAR:
On-Demand

Desktop-as-a-Service Designed for Any Cloud ? Nutanix Frame


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.

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]

RTTI syntax

WEBINAR:
On-Demand

Desktop-as-a-Service Designed for Any Cloud ? Nutanix Frame


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.

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]



Most Popular Programming Stories

More for Developers

RSS Feeds

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