Java, unlike C++, maintains a clear object oriented
structure after compilation, . The class definition - the fields,
methods and constructors - is contained in its own object of type
Class. (this
leads to the redundant and rather confusing
Class
class nomenclature!)
That is, every class, such as Object,
String
or Thread,
has a corresponding Class
object that is actually responsible for creating the objects of
that particular type. (Even the primitive
types and void
have a corresponding Class
object to describe them even though they are not classes in the
usual sense.)
This higher level abstraction can be confusing but
one doesn't need to understand it very deeply to take advantage
of the tools that Class
provides.
Class
is an important part of Java's ability to dynamically
(while the program is running rather than during compilation)
load new classes and create objects from them. We discussed in
Chapter 4: Adv : Class
Loading how each class file is loaded by a class loader object.
The Class
object can be obtained from
- An object:
String
str = "A string";
Class c = str.getClass();
- The name of a class:
Class c = Class.forName("String");
- The class type:
Class c = String.class;
Note that the .class
is not a field in the String
or Object
classes but is an operator detected by the compiler.
Inversely, we can use Class
to find out what is the name of the class type of an unknown object
Class
c = str.getClass();
System.out.println(c.getName());
And Class
objects can create instances of the class type they represent:
try
{
String newStr = (String)c.newInstance();
}
catch (InstantiationException e)
{}
catch (IllegalAccessException e)
{}
Class
has many other methods, with many especially intended to provide
information on the class description (see the page on Reflection).
These include various getter methods, such as getMethods()and
getFields(),
that return reflection objects that represent the properties of
the class.
With the above techniques, you can get some idea
of how Java dynamically loads a class. Classes in Java are only
loaded when they are needed. When the class is needed, the JVM
gives the class name (and other location info such as a URL or
JAR file name) to a class
loader that finds the class and creates a Class
instance for the class. Then the JVM will use the Class
object to create an instance of the class.
getResource()
Every class has a class
loader that found the original class file (on local disk or
over the network) and loaded the Class
object. The class loader for a particular class can be found via
the getClassLoader()
method in Class.
Class loaders know about communicating with the
outside environment and can be used for obtaining other resources
besides class files. For example, to load an image or audio file
from a JAR
file, you can use the getResource()
method in Class
as in
URL
url = getClass().getResource("image.gif");
ImageIcon icon = new ImageIcon(url);
The getResource()
method in Class
actually uses the class loader object. So an alternative is to
ask for the class loader directly and use its getResource()
method as in
URL url =
this.getClass().getClassLoader().getResource("image.gif");
ImageIcon icon = new ImageIcon(url);
This surely seems a rather obscure way to carry
out the simple task of obtaining an image file but at least it
provides some insight into the inner workings of the JVM and class
construction.
References & Web
Resources