Class类:
程序运行时,Java运行时系统维护了一份所有对象的运行时类型识别。保持了每个对象的类的信息。虚拟机根据运行时类别信息,选择正确的方法来执行。
For example, the statement
我们也可以使用一个特殊的Java类来获得这些信息。这个类就是Class类。对一个对象使用getClass()方法可以获得Class类型的一个实例。例如:
Employee e;
Class cl = e.getClass();
正如一个Employee对象描述了一个特定的雇员的信息一样,一个Class对象描述了一个特定的Class的信息。Class类最有用的方法大概是getName(),此方法返回了对象的类名。
例如,如果e是一个Employee类对象,语句:
System.out.println(e.getClass().getName() + " " + e.getName());
打印出:
Employee Harry Hacker
还可以使用静态方法forName(),通过一个字符串来获得类对象。
String className = "java.util.Date";
Class cl = Class.forName(className);
如果类名保存在一个字符串中可以使用forName方法来获得Class对象,这在className是一个类或者接口的名称时,会起作用。否则,会抛出异常。
TIP
当启动时,包含main方法的类被加载。并加载它所需要的所有的类,这些类又加载它们用到的类,依此类推。这样一个大应用程序可能会花费较长的时间,使用户感到不快。可以采用下面的方法,给用户程序更快的启动的错觉。确保main方法没有显式的引用其它类。然后通过调用Class.forName来强制加载其他类。
第三种获得类对象的方法,如果T是一个java类,T.class返回匹配的类对象。例如:
Class cl1 = Date.class; // if you import java.util.*;
Class cl2 = int.class;
Class cl3 = Double[].class;
Class对象描述了一个类型,这个类型也可能不是一个类。例如,int不是一个类,int.class仍然是一个Class类型的对象。
使用Class对象的newInstance()方法,可以获得一个对象的实例。例如:
String s = "java.util.Date";
Object m = Class.forName(s).newInstance();
newInstance使用默认的构造函数,如果没有默认构造函数,会抛出异常。
Using Reflection to Analyze the Capabilities of Classes
Here is a brief overview of the most important parts of the reflection mechanism for letting you examine the structure of a class.
API
java.lang.Class 1.0
static Class forName(String className)
returns the Class object representing the class with name className.
Object newInstance()
returns a new instance of this class.
java.lang.reflect.Constructor 1.1
Object newInstance(Object[] args)
constructs a new instance of the constructor's declaring class.
Parameters:
args
the parameters supplied to the constructor. See the section on reflection for more information on how to supply parameters.
java.lang.Throwable 1.0
void printStackTrace()
prints the Throwable object and the stack trace to the standard error stream.
使用反射来分析类
Here is a brief overview of the most important parts of the reflection mechanism for letting you examine the structure of a class.
这儿是简要的介绍反射机制最重要的部分,使用它们可以考查一个类的结构。
All you have to do is have the appropriate method in the Modifier class work on the integer that getModifiers returns. You can also use the Modifier.toString method to print the modifiers.
java.lang.reflect包中Field,Method和Constructor这3个类,分别用来描述一个类的Field,Method和Constructor。这3个类都有一个名为getName的方法,用来获得项目的名字。Field类有个getType()方法,又返回一个Class对象,描述这个字段的类型。Method和Constructor类都有获得参数类型的方法,Method类得到了返回类型。3个类都有返回类型为Integer的getModifiers方法,获得修饰,例如public或者static等。还可以使用java.lang.reflect包中的Modifier类来分析getModifiers的Integer类型返回值。使用Modifier类的isPublic,isPrivate,isFinal方法来获知一个方法或者构造函数是否是public, private, or final。你所需要做的是使用合适的方法对getModifiers返回的整型值进行操作。也可以使用Modifier.toString()方法来打印修饰符。
Class类的getFields, getMethods, getConstructors方法获得公共fields,methods和constructors的数组。也包含了超类的公共成员。getdeclaredFields,geTDeclaredMethods和geTDeclaredConstructors方法可以获得Class类中声明的所有的fields,方法和构造函数。包含了private和protected成员,但是不包含超类中的成员。
例子5-5显示了如何打印出一个类的所有信息。这个程序提示你输入一个类名,打印出所有的数据成员,方法和构造函数。例如,你输入:
java.lang.Double
程序打印出:
class java.lang.Double extends java.lang.Number
{
public java.lang.Double(java.lang.String);
public java.lang.Double(double);
public int hashCode();
public int compareTo(java.lang.Object);
public int compareTo(java.lang.Double);
public boolean equals(java.lang.Object);
public java.lang.String toString();
public static java.lang.String toString(double);
public static java.lang.Double valueOf(java.lang.String);
public static boolean isNaN(double);
public boolean isNaN();
public static boolean isInfinite(double);
public boolean isInfinite();
public byte byteValue();
public short shortValue();
public int intValue();
public long longValue();
public float floatValue();
public double doubleValue();
public static double parseDouble(java.lang.String);
public static native long doubleToLongBits(double);
public static native long doubleToRawLongBits(double);
public static native double longBitsToDouble(long);
public static final double POSITIVE_INFINITY;
public static final double NEGATIVE_INFINITY;
public static final double NaN;
public static final double MAX_VALUE;
public static final double MIN_VALUE;
public static final java.lang.Class TYPE;
private double value;
private static final long serialVersionUID;
}
这个程序可以分析任何java解释器可以加载的类,而不仅仅是程序编译时的类。
Example 5-5. ReflectionTest.java
import java.lang.reflect. * ;
public class ReflectionTest {
public static void main(String[] args) {
// read class name from command-line args or user input
String name;
if (args.length > 0 )
name = args[ 0 ];
else {
Scanner in = new Scanner(System.in);
System.out.println( " Enter class name (e.g. java.util.Date): " );
name = in.next();
}
try {
// print class name and superclass name (if != Object)
Class cl = Class.forName(name);
Class supercl = cl.getSuperclass();
System.out.print( " class " + name);
if (supercl != null && supercl != Object. class )
System.out.print( " extends " + supercl.getName());
System.out.print( " \n{\n " );
printConstructors(cl);
System.out.println();
printMethods(cl);
System.out.println();
printFields(cl);
System.out.println( " } " );
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
System.exit( 0 );
}
/**
* Prints all constructors of a class
*
* @param cl
* a class
*/
public static void printConstructors(Class cl)
{
Constructor[] constructors = cl.getDeclaredConstructors();
for (Constructor c : constructors)
{
String name = c.getName();
System.out.print( " " + Modifier.toString(c.getModifiers()));
System.out.print( " " + name + " ( " );
// print parameter types
Class[] paramTypes = c.getParameterTypes();
for ( int j = 0 ; j < paramTypes.length; j ++ )
{
if (j > 0 ) System.out.print( " , " );
System.out.print(paramTypes[j].getName());
}
System.out.println( " ); " );
}
}
/**
* Prints all methods of a class
*
* @param cl
* a class
*/
public static void printMethods(Class cl)
{
Method[] methods = cl.getDeclaredMethods();
for (Method m : methods)
{
Class retType = m.getReturnType();
String name = m.getName();
// print modifiers, return type and method name
System.out.print( " " + Modifier.toString(m.getModifiers()));
System.out.print( " " + retType.getName() + " " + name + " ( " );
// print parameter types
Class[] paramTypes = m.getParameterTypes();
for ( int j = 0 ; j < paramTypes.length; j ++ )
{
if (j > 0 ) System.out.print( " , " );
System.out.print(paramTypes[j].getName());
}
System.out.println( " ); " );
}
}
/**
* Prints all fields of a class
*
* @param cl
* a class
*/
public static void printFields(Class cl)
{
Field[] fields = cl.getDeclaredFields();
for (Field f : fields)
{
Class type = f.getType();
String name = f.getName();
System.out.print( " " + Modifier.toString(f.getModifiers()));
System.out.println( " " + type.getName() + " " + name + " ; " );
}
}
}
API
java.lang.Class 1.0
Field[] getFields() 1.1
Field[] getDeclaredFields() 1.1
The getFields method returns an array containing Field objects for the public fields of this class or its superclasses. The geTDeclaredField method returns an array of Field objects for all fields of this class. The methods return an array of length 0 if there are no such fields or if the Class object represents a primitive or array type.
Method[] getMethods() 1.1
Method[] getDeclaredMethods() 1.1
return an array containing Method objects: getMethods returns public methods and includes inherited methods; getdeclaredMethods returns all methods of this class or interface but does not include inherited methods.
Constructor[] getConstructors() 1.1
Constructor[] getDeclaredConstructors() 1.1
return an array containing Constructor objects that give you all the public constructors (for getConstructors) or all constructors (for getdeclaredConstructors) of the class represented by this Class object.
java.lang.reflect.Field 1.1
java.lang.reflect.Method 1.1
java.lang.reflect.Constructor 1.1
Class getDeclaringClass()
returns the Class object for the class that defines this constructor, method, or field.
Class[] getExceptionTypes() (in Constructor and Method classes)
returns an array of Class objects that represent the types of the exceptions thrown by the method.
int getModifiers()
returns an integer that describes the modifiers of this constructor, method, or field. Use the methods in the Modifier class to analyze the return value.
String getName()
returns a string that is the name of the constructor, method, or field.
Class[] getParameterTypes() (in Constructor and Method classes)
returns an array of Class objects that represent the types of the parameters.
Class getReturnType() (in Method classes)
returns a Class object that represents the return type.
java.lang.reflect.Modifier 1.1
static String toString(int modifiers)
returns a string with the modifiers that correspond to the bits set in modifiers.
static boolean isAbstract(int modifiers)
static boolean isFinal(int modifiers)
static boolean isInterface(int modifiers)
static boolean isNative(int modifiers)
static boolean isPrivate(int modifiers)
static boolean isProtected(int modifiers)
static boolean isPublic(int modifiers)
static boolean isStatic(int modifiers)
static boolean isStrict(int modifiers)
static boolean isSynchronized(int modifiers)
static boolean isVolatile(int modifiers)
These methods test the bit in the modifiers value that corresponds to the modifier in the method name.
使用Reflection在运行时分析对象