Java in a Nutshell, 5th Edition [Electronic resources] نسخه متنی

اینجــــا یک کتابخانه دیجیتالی است

با بیش از 100000 منبع الکترونیکی رایگان به زبان فارسی ، عربی و انگلیسی

Java in a Nutshell, 5th Edition [Electronic resources] - نسخه متنی

| نمايش فراداده ، افزودن یک نقد و بررسی
افزودن به کتابخانه شخصی
ارسال به دوستان
جستجو در متن کتاب
بیشتر
تنظیمات قلم

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

روز نیمروز شب
جستجو در لغت نامه
بیشتر
لیست موضوعات
توضیحات
افزودن یادداشت جدید


5.13. Types, Reflection, and Dynamic Loading



The
java.lang.Class
class represents data
types in Java and, along with the classes in the
java.lang.reflect package, gives Java programs the
capability of introspection (or self-reflection); a Java class can
look at itself, or any other class, and determine its superclass,
what methods it defines, and so on.


5.13.1. Class Objects


You can obtain a Class object in Java in several
ways:

// Obtain the Class of an arbitrary object o
Class c = o.getClass();
// Obtain a Class object for primitive types with various predefined constants
c = Void.TYPE; // The special "no-return-value" type
c = Byte.TYPE; // Class object that represents a byte
c = Integer.TYPE; // Class object that represents an int
c = Double.TYPE; // etc; see also Short, Character, Long, Float
// Express a class literal as a type name followed by ".class"
c = int.class; // Same as Integer.TYPE
c = String.class; // Same as "dummystring".getClass()
c = byte[].class; // Type of byte arrays
c = Class[][].class; // Type of array of arrays of Class objects


5.13.2. Reflecting on a Class


Once you have a Class object, you can perform some
interesting reflective operations with it:

import java.lang.reflect.*;
Object o; // Some unknown object to investigate
Class c = o.getClass(); // Get its type
// If it is an array, figure out its base type
while (c.isArray()) c = c.getComponentType();
// If c is not a primitive type, print its class hierarchy
if (!c.isPrimitive()) {
for(Class s = c; s != null; s = s.getSuperclass())
System.out.println(s.getName() + " extends");
}
// Try to create a new instance of c; this requires a no-arg constructor
Object newobj = null;
try { newobj = c.newInstance(); }
catch (Exception e) {
// Handle InstantiationException, IllegalAccessException
}
// See if the class has a method named setText that takes a single String
// If so, call it with a string argument
try {
Method m = c.getMethod("setText", new Class[] { String.class });
m.invoke(newobj, new Object[] { "My Label" });
} catch(Exception e) { /* Handle exceptions here */ }
// These are varargs methods in Java 5.0 so the syntax is much cleaner.
// Look for and invoke a method named "put" that takes two Object arguments
try {
Method m = c.getMethod("add", Object.class, Object.class);
m.invoke(newobj, "key", "value");
} catch(Exception e) { System.out.println(e); }
// In Java 5.0 we can use reflection on enumerated types and constants
Class<Thread.State> ts = Thread.State.class; // Thread.State type
if (ts.isEnum()) { // If it is an enumerated type
Thread.State[] constants = ts.getEnumConstants(); // get its constants
}
try {
Field f = ts.getField("RUNNABLE"); // Get the field named "RUNNABLE"
System.out.println(f.isEnumConstant()); // Is it an enumerated constant?
}
catch(Exception e) { System.out.println(e); }
// The VM discards generic type information at runtime, but it is stored
// in the class file for the compiler and is accessible through reflection
try {
Class map = Class.forName("java.util.Map");
TypeVariable<?>[] typevars = map.getTypeParameters();
for(TypeVariable<?> typevar : typevars) {
System.out.print(typevar.getName());
Type[] bounds = typevar.getBounds();
if (bounds.length > 0) System.out.print(" extends ");
for(int i = 0; i < bounds.length; i++) {
if (i > 0) System.out.print(" & ");
System.out.print(bounds[i]);
}
System.out.println();
}
}
catch(Exception e) { System.out.println(e); }
// In Java 5.0, reflection can also be used on annotation types and to
// determine the values of runtime visible annotations
Class<?> a = Override.class; // an annotation class
if (a.isAnnotation()) { // is this an annotation type?
// Look for some meta-annotations
java.lang.annotation.Retention retention =
a.getAnnotation(java.lang.annotation.Retention.class);
if (retention != null)
System.out.printf("Retention: %s%n", retention.value());
}


5.13.3. Dynamic Class Loading




Class also provides a
simple mechanism for dynamic class loading in Java. For more complete
control over dynamic class loading, however, you should use a
java.lang.ClassLoader object, typically a
java.net.URLClassLoader. This technique is useful,
for example, when you want to load a class that is named in a
configuration file instead of being hardcoded into your program:

// Dynamically load a class specified by name in a config file
String classname = // Look up the name of the class
config.getProperty("filterclass", // The property name
"com.davidflanagan.filters.Default"); // A default
try {
Class c = Class.forName(classname); // Dynamically load the class
Object o = c.newInstance(); // Dynamically instantiate it
} catch (Exception e) { /* Handle exceptions */ }

The preceding code works only if the class to be loaded is in the
class path. If this is not the case, you can create a custom
ClassLoader object to load a class from a path (or
URL) you specify yourself:

import java.net.*;
String classdir = config.getProperty("filterDirectory"); // Look up class path
try {
ClassLoader loader = new URLClassLoader(new URL[] { new URL(classdir) });
Class c = loader.loadClass(classname);
}
catch (Exception e) { /* Handle exceptions */ }


5.13.4. Dynamic Proxies




The Proxy
class and InvocationHandler interface to the
java.lang.reflect package were added to Java 1.3.
Proxy is a powerful but infrequently used class
that allows you to dynamically create a new class or instance that
implements a specified interface or set of interfaces. It also
dispatches invocations of the interface methods to an InvocationHandler

object.


/ 1191