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

原创 2004年07月13日 10:14:00

本文涉及的JavaAPI有:

java.lang包中的Class类,java.lang.reflect包中的Field,Method,Constructor,Modifier类

基本编程思路:

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

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

Field[] fields =  Class.getDeclaredFields();   

for (i = 0; i < fields.length; i++)

{

            Field f = fields[i];

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

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

            println(Modifier.toString(f.getModifiers()));

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

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

            println("  "+ type.getName() + "  "+ name);

            //type.getName()返回数据类型名称

}

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

import java.lang.reflect.*;
import javax.swing.*;

public class ReflectTest
{
    public static void main(String[] args)
    {
        String name;
        if (args.length > 0)
            name = args[0];
        else
            name = JOptionPane.showInputDialog("输入一个类名:按(java.lang.Double)格式");
       
        try
        {
            Class cl = Class.forName(name);
            Class supercl = cl.getSuperclass(); //获得超类的Class对象
            System.out.println("class "+ name);
            //判断超类是否为空或为Object
            if (supercl != null && supercl != Object.class)
                System.out.println("extends "+ supercl.getName());
           
            System.out.print("/n{/n");
            printConstructors(cl);
            System.out.println();
            printMethods(cl);
            System.out.println();
            printField(cl);
            System.out.println("}");
        }
        //当使用class对象时注意捕获该异常,异常为类型未创建
        catch(ClassNotFoundException e)
        {
            e.printStackTrace();
            System.out.println("类型未创建");
        }
        System.exit(0);
    }
   
    /**
     *该方法打印构造器的详细信息
     */
    public static void printConstructors(Class cl)
    {
        //定义构造器数组
        Constructor[] constructors = cl.getDeclaredConstructors();
       
        for (int i = 0; i < constructors.length; i++)
        {
            //将数组元素赋给一个构造器对象
            Constructor constr = constructors[i];
            String name = constr.getName(); //获取构造器名称
            //打印访问修饰符
            System.out.print(Modifier.toString(constr.getModifiers()));
            System.out.print("  "+ name + "(");
           
            /**
             *定义一个参数类型数组该数组是Class对象
             *getParameterTypes()返回该构造器参数类型的数组
             *打印参数类型名称
             */
            Class[] paramTypes = constr.getParameterTypes();
            for (int j = 0; j < paramTypes.length; j++)
            {
                if (j > 0) System.out.print(", ");
                System.out.print(paramTypes[j].getName());
            }
            System.out.println(");");
        }
    }
   
    /**
     *该方法打印方法的详细信息
     */
    public static void printMethods(Class cl)
    {
        Method[] methods = cl.getDeclaredMethods();
       
        for (int i = 0; i < methods.length; i++)
        {
            Method m = methods[i];
            Class retType = m.getReturnType();
            String name = m.getName();
           
            System.out.print(Modifier.toString(m.getModifiers()));
            System.out.print("  "+ retType.getName() +" "+ name + "(");
           
            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(");");
        }
    }
   
    /**
     *该方法打印字段的详细信息
     */
    public static void printField(Class cl)
    {
        Field[] fields = cl.getDeclaredFields();
       
        for (int i = 0; i < fields.length; i++)
        {
            Field f =fields[i];
            Class type = f.getType();
            String name = f.getName();
            System.out.print(Modifier.toString(f.getModifiers()));
            System.out.println("  "+ type.getName() +" "+ name + ";");
        }
    }
}

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

JAVA reflect (反射) 分析类结构

一、数据准备Java反射用到的Human类package ReflectAnalysis;public class Human { public String name; privat...
  • tterminator
  • tterminator
  • 2016年04月26日 13:25
  • 666

通过反射输入一个类,打印出类中所有元素

代码如下: import java.util.*; import java.lang.reflect.*; /** 反射---输入一个类,打印出类中所有元素 reflect包中有三个描述类元素的类:...
  • hj7jay
  • hj7jay
  • 2017年05月26日 09:17
  • 346

Java学习之类加载全过程_JVM内存分析_反射机制核心原理_常量池理解

一、类加载机制 JVM把class文件加载到内存,并对数据进行校验,解析和初始化,最形成JVM可以直接使用的JAVA类型的过程。加载-->链接(-->验证-->准备-->解析)-->初始化-->使用...
  • haitaofeiyang
  • haitaofeiyang
  • 2015年03月14日 23:14
  • 2280

java - 通过反射调用类的完整结构

Class 获取属性 getFields(); 只能获取到运行时类中及其父类声明public的属性 返回的值是 Flield[] 数组 属性的数组 getDelaredFields(); ...
  • x_zcl
  • x_zcl
  • 2016年07月13日 23:39
  • 284

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

  • zgqtxwd
  • zgqtxwd
  • 2008年04月25日 05:14
  • 114

使用Java的反射功能调用类中的方法

最近一直在搞Java的反射,今天使用反射调用方法时出现了很多问题,主要是没有详细参考官方API。所以走了很多弯路。 所以想把这个例子记下来,供自己也供他人学习。...
  • baidu_18607183
  • baidu_18607183
  • 2014年11月05日 10:57
  • 825

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

基本编程思路:       首先要获取需要进行分析的类的名称,将类名称指定到Class类中的forName(String  classname)方法为参数,调用该方法后将返回一个该指定类型的Class...
  • passren
  • passren
  • 2004年07月16日 10:16
  • 668

利用java反射机制实现动态向下转型

 前段时间我在使用hibernate的时候突然想到一个问题:我经常要对数据库中某条记录中的某个字段读取后进行判断,一般正规的操作流程是先使用session.get方法读取这条记录,并将其保存进一个hi...
  • xhdwell
  • xhdwell
  • 2009年03月08日 17:32
  • 1232

利用java反射机制动态加载apk需要注意几点

一:一个安装的apk里面的一个TestA要去调用一个放在sd卡上的没安装的apk里面的TestB。 二:TestBActivity运行会报错,大伙不用管,只要拿到TestBActivity运行后的a...
  • u012439662
  • u012439662
  • 2014年07月07日 15:56
  • 370

Java 利用反射调用jar包中的类

下面讲展示的是从image.jar包中调用image.Buddy类的方法。 public class Main { public static void main(String[] arg...
  • sinat_16492463
  • sinat_16492463
  • 2015年04月03日 12:31
  • 5226
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:在Java中使用反射分析类结构
举报原因:
原因补充:

(最多只允许输入30个字)