To understand how Rtti works in Java, you first have to understand how the type information is expressed at run time. A special form of object called "Class object" is used to include information about the class (sometimes called "Meta class"). In fact, we're going to use the class object to create all the "normal" or "normal" objects that belong to a class. The
has a class object for each class that is part of the program. In other words, each time you write a new class, you also create a class object (or, more appropriately, A. class file with the exact same name). At runtime, once we want to generate an object for that class, the Java Virtual Machine (JVM) that executes the program first checks to see if that type of class object is loaded. If it is not already loaded, the JVM looks for the. class file with the same name and loads it. So Java programs are not fully loaded when started, which is different from many traditional languages.
Once the class object of that type enters memory, it is used to create all objects of that type.
If this is a bit confusing to you, or if you don't really understand it, the following model program might be able to provide further help:
//: Sweetshop.java//examination of the way the class loader works class Candy {static {Sys
Tem.out.println ("Loading Candy");
} class Gum {static {System.out.println ("Loading Gum");
} class Cookie {static {System.out.println ("Loading cookie");
} public class Sweetshop {public static void main (string[] args) {SYSTEM.OUT.PRINTLN ("inside main");
New Candy ();
System.out.println ("After creating Candy");
try {class.forname ("Gum");
catch (ClassNotFoundException e) {e.printstacktrace ();
} System.out.println ("After Class.forName (\ gum\)");
New Cookie ();
System.out.println ("After creating Cookie"); }
} ///:~
For each class (Candy,gum and cookies), they all have a static clause that executes when the class is first loaded. The corresponding information will be printed out to tell us when the load was carried out. In main (), the creation code for the object is located between the print statements to detect the loading time.
A particularly interesting line is:
Class.forName ("Gum");
The method is a static member of Class (that is, all classes are subordinate). The class object is similar to any other object, so it is possible to acquire and control one of its handles (the load module is the thing). One way to get a handle to class is to use forname (). Its function is to obtain a string containing the name of the target class text (note spelling and capitalization). The last return is a class handle.
The output of the program in one JVM is as follows:
Inside main
Loading Candy after creating Candy Loading Gum after
class.forname ("Gum")
Loading Cookies after
creating cookies
As you can see, each class is loaded only when it is needed, and the static initialization work is performed when the class is loaded.
Interestingly, the output of another JVM becomes another:
Loading Candy
Loading Cookie
inside main after
creating
Candy Loading Class.forName ("Gum") after
creating Cookie
It appears that the JVM has predicted the need for candy and cookies by examining the code in main (), but does not see gum because it was created by a call to forname (), rather than by a more typical new call. Even though the JVM is doing what we want, because it does load those classes before we need to, we can't be sure that the behavior is absolutely correct.
1. Class Mark
In Java 1.1, there is a second way to produce a handle to a class object: Using the class tag. For the above procedure, it looks like the following:
Gum.class;
This is not only simpler, but also more secure, because it will be checked during compilation. Because it cancels the need for method calls, the execution efficiency is also higher.
Class tags can be applied not only to ordinary classes, but also to interfaces, arrays, and basic data types. In addition, there is a standard field named type for the wrapper class for each of the base data types. The role of type field is to produce a handle to the class object for the underlying data type, as follows:
...... Be equivalent to ...
... is equivalent to ...
|
Boolean.class
|
Boolean.type
|
Char.class
|
Character.type
|
Byte.class
|
Byte.type
|
Short.class
|
Short.type
|
Int.class
|
Integer.type
|
Long.class
|
Long.type
|
Float.class
|
Float.type
|
Double.class
|
Double.type
|
Void.class
|
Void.type
|