java

位置:IT落伍者 >> java >> 浏览文章

在Java中使用反射分析类结构


发布日期:2020年04月26日
 
在Java中使用反射分析类结构

首先要获取需要进行分析的类的名称将类名称指定到Class类中的forName(Stringclassname)方法为参数调用该方法后将返回一个该指定类型的Class对象Class对象描述了该类型的详细信息其中一些重要的方法包括getFields()getMethods()getConstructors()这些方法分别返回该类型中支持的公有字段方法和构造器数组其中包含超类的公有成员而同是Class中以上的方法名称中加入了Declared的方法则返回该类型中定义的所有成员包括私有的但不包括超类成员现在我们已经获得了该类型的字段方法和构造器数组接着我们使用javalangreflect包中的FieldMethodConstructor类来获得字段方法和构造器的详细信息例如我们要显示该类型中的所有的字段信息伪代码

//getDeclaredFields返回所有定义的字段数组

Field[] fields =ClassgetDeclaredFields();

for (i = ; i < fieldslength; i++)

{

Field f = fields[i];

Class type = fgetType(); //getType()返回字段的数据类型

String name = fgetName(); //getName()返回字段名称

println(ModifiertoString(fgetModifiers()));

//getModifiers()返回一个代表访问控制符的整数

//ModifiertoString()将该整数转换为对应的访问控制符字符串

println(+ typegetName() + + name);

//typegetName()返回数据类型名称

}

好了下面看一个完整的例子例子长了一点不过很简单!

import javalangreflect*;

import javaxswing*;

public class ReflectTest

{

public static void main(String[] args)

{

String name;

if (argslength > )

name = args[];

else

name = JOptionPaneshowInputDialog(输入一个类名:按(javalangDouble)格式);

try

{

Class cl = ClassforName(name);

Class supercl = clgetSuperclass(); //获得超类的Class对象

Systemoutprintln(class + name);

//判断超类是否为空或为Object

if (supercl != null && supercl != Objectclass)

Systemoutprintln(extends + superclgetName());

Systemoutprint(\n{\n);

printConstructors(cl);

Systemoutprintln();

printMethods(cl);

Systemoutprintln();

printField(cl);

Systemoutprintln(});

}

//当使用class对象时注意捕获该异常异常为类型未创建

catch(ClassNotFoundException e)

{

eprintStackTrace();

Systemoutprintln(类型未创建);

}

Systemexit();

}

/**

*该方法打印构造器的详细信息

*/

public static void printConstructors(Class cl)

{

//定义构造器数组

Constructor[] constructors = clgetDeclaredConstructors();

for (int i = ; i < constructorslength; i++)

{

//将数组元素赋给一个构造器对象

Constructor constr = constructors[i];

String name = constrgetName(); //获取构造器名称

//打印访问修饰符

Systemoutprint(ModifiertoString(constrgetModifiers()));

Systemoutprint(+ name + ();

/**

*定义一个参数类型数组该数组是Class对象

*getParameterTypes()返回该构造器参数类型的数组

*打印参数类型名称

*/

Class[] paramTypes = constrgetParameterTypes();

for (int j = ; j < paramTypeslength; j++)

{

if (j > ) Systemoutprint( );

Systemoutprint(paramTypes[j]getName());

}

Systemoutprintln(););

}

}

/**

*该方法打印方法的详细信息

*/

public static void printMethods(Class cl)

{

Method[] methods = clgetDeclaredMethods();

for (int i = ; i < methodslength; i++)

{

Method m = methods[i];

Class retType = mgetReturnType();

String name = mgetName();

Systemoutprint(ModifiertoString(mgetModifiers()));

Systemoutprint(+ retTypegetName() + + name + ();

Class[] paramTypes = mgetParameterTypes();

for (int j = ; j < paramTypeslength; j++)

{

if (j > ) Systemoutprint( );

Systemoutprint(paramTypes[j]getName());

}

Systemoutprintln(););

}

}

/**

*该方法打印字段的详细信息

*/

public static void printField(Class cl)

{

Field[] fields = clgetDeclaredFields();

for (int i = ; i < fieldslength; i++)

{

Field f =fields[i];

Class type = fgetType();

String name = fgetName();

Systemoutprint(ModifiertoString(fgetModifiers()));

Systemoutprintln(+ typegetName() + + name + ;);

}

}

}

我经常遇到这样的问题比如当我要写一个接受命令行参数的程序时我通常是先打开NetBeans工具写完并保存后有回到命令提示符上使用javac编译java运行为什么?因为用开发环境运行的话接收不了命令行参数而会抛出一个异常我是不是很蠢其实用一个JOptionPaneshowInputDialog可以避免发生这样的事情只需加一个判断我们编程的良好风格是多关心如何编写稳重的代码而不是动不动就捕捉异常!               

上一篇:java抽取word,pdf的四种武器

下一篇:使用Java自带SAX工具解析XML