Java学习者论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

恭喜Java学习者论坛(https://www.javaxxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,购买链接:点击进入购买VIP会员
JAVA高级面试进阶视频教程Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程

Go语言视频零基础入门到精通

Java架构师3期(课件+源码)

Java开发全终端实战租房项目视频教程

SpringBoot2.X入门到高级使用教程

大数据培训第六期全套视频教程

深度学习(CNN RNN GAN)算法原理

Java亿级流量电商系统视频教程

互联网架构师视频教程

年薪50万Spark2.0从入门到精通

年薪50万!人工智能学习路线教程

年薪50万!大数据从入门到精通学习路线年薪50万!机器学习入门到精通视频教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程 MySQL入门到精通教程
查看: 235|回复: 0

[Java反射学习]在Java中使用反射分析类结构

[复制链接]
  • TA的每日心情
    开心
    2021-3-12 23:18
  • 签到天数: 2 天

    [LV.1]初来乍到

    发表于 2014-10-31 23:58:27 | 显示全部楼层 |阅读模式
    本文涉及的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;

                 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("
    {
    ");
                 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;
                 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;
                 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;
                 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可以避免发生这样的事情,只需加一个判断,我们编程的良好风格是多关心如何编写稳重的代码,而不是动不动就捕捉异常
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|Java学习者论坛 ( 声明:本站资料整理自互联网,用于Java学习者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-5-18 23:44 , Processed in 0.477441 second(s), 46 queries .

    Powered by Discuz! X3.4

    © 2001-2017 Comsenz Inc.

    快速回复 返回顶部 返回列表