|
|
Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs
Page 2 of 5
For every type it loads, the JVM creates an instance of class java.lang.Class to "represent" the type to the application. Arrays, because they are full-class objects in Java, get Class objects too. (Every array of the same element type and dimension shares the same Class object.) A Class object gives you access to the information stored in the method area for the type the Class object represents.
Although the Java specifications don't define a layout or organization for objects on the heap -- that is the decision of each JVM designer -- the specifications require that object images be in some way connected to the type data for the object's class. One approach open to a JVM designer, for example, is to include a pointer into the method area as part of each object image. Given only a reference to an object, every JVM must be able to get at the type information stored in the method area for that object.
Now that you know that all this class information is available for every object on the heap, how do you get at it? Java gives you many ways to make use of the information stored in the method area:
instanceof operator
java.lang.ClassPerhaps the simplest way to use runtime class information is to perform a cast. As one of Java's security mechanisms, JVMs
check all casts at runtime for validity. If you have a reference of type Object and try to cast it to type Hippopotamus, for example, the JVM will in some way check to make sure the cast is valid. This check makes use of runtime class information.
If the cast isn't valid, the JVM will throw a ClassCastException exception.
Casts, depending on how they are used, can help or hinder code flexibility. It is usually helpful to upcast -- to cast from a subtype to a supertype. A basic guideline for making flexible object-oriented designs is to treat objects as generically as possible -- to make the type of your variables as far up the inheritance hierarchy as possible.
If you have code that must manipulate a Hippopotamus object, for example, you can hold a reference to it in a variable of type Hippopotamus. But if your class Hippopotamus extends class Animal and what you are doing is something you might consider doing to any kind of animal, not just hippopotami, you should consider
upcasting your reference to Animal. You could use that same code later on for instances of other subclasses of Animal, such as Cats or Dogs, not just Hippopotamus objects.
In contrast to upcasts, downcasts (casts from a supertype to a subtype) can be more troublesome to flexibility. In general, instead of doing explicit downcasts, you should strive to let dynamic binding make polymorphism work for you.
Downcasts often are used in combination with the instanceof operator. instanceof is another of Java's mechanisms that use runtime class information. When the JVM executes an instanceof operation, it consults the runtime class information associated with an object reference to determine whether the object
is or is not an instance of the specified class. Like downcasts, instanceof can potentially work against the goal of flexibility.