网络编程 | 站长之家 | 网页制作 | 图形图象 | 操作系统 | 冲浪宝典 | 软件教学 | 网络办公 | 邮件系统 | 网络安全 | 认证考试 | 系统进程
Firefox | IE | Maxthon | 迅雷 | 电驴 | BitComet | FlashGet | QQ | QQ空间 | Vista | 输入法 | Ghost | Word | Excel | wps | Powerpoint
asp | .net | php | jsp | Sql | c# | Ajax | xml | Dreamweaver | FrontPages | Javascript | css | photoshop | fireworks | Flash | Cad | Discuz!
当前位置 > 网站建设学院 > 网络编程 > Java
Tag:注入,存储过程,分页,安全,优化,xmlhttp,fso,jmail,application,session,防盗链,stream,无组件,组件,md5,乱码,缓存,加密,验证码,算法,cookies,ubb,正则表达式,水印,索引,日志,压缩,base64,url重写,上传,控件,Web.config,JDBC,函数,内存,PDF,迁移,结构,破解,编译,配置,进程,分词,IIS,Apache,Tomcat,phpmyadmin,Gzip,触发器,socket
网络编程:ASP教程,ASP.NET教程,PHP教程,JSP教程,C#教程,数据库,XML教程,Ajax,Java,Perl,Shell,VB教程,Delphi,C/C++教程,软件工程,J2EE/J2ME,移动开发
本月文章推荐
.JBuilderX 常见问题FAQ.
.技巧-优化Derby数据库.
.留言板.
.我对类,方法 ,接口的认识.
.Java how to program(Third Edi.
.用JAVA编写自己的机器人,然后一.
.“谁持彩练当空舞”-- 看Java、C.
.java、J2EE基础问题汇总.
.JBuilderX+SQL Server开发hibern.
.用Java构造自己的媒体播放器.
.基于Java 开发QuickTime&nb.
.适用于SQL Server的Select检索高.
.[JAVA100例]048、使用JavaMail接.
.原始模型模式.
.Java程序员需要了解的几个开源协.
.Java与C++.
.J2ME中定点库MathFP使用入门.
.如何使用JSTL标签做页面资源国际.
.图像与声音.
.教你如何编写Java类(一).

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

发表日期:2008-1-5



  首先要获取需要进行分析的类的名称,将类名称指定到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中编程实现数字签名系统 人气:668
下一篇:通过 Java 如何实现 AES 密码算法 人气:1297
浏览全部Java的内容 Dreamweaver插件下载 网页广告代码 祝你圣诞节快乐 2009年新年快乐