(一)Deep In Java之反射初探

一 前言

    面对一个新鲜的事物,当我接触它的时候,我总是习惯于先观其表象,再剖其本质,先宏观了解,再微观入手。根据事物的表象,去不断提问,为什么是这样的,为什么它可以这样。提出问题,解答问题,一点一点剖析其本质,这成了我一直使用的学习方式。我本着交流与互换意见的意图,在我的博客中与大家交流我在深入底层时的理解与一些观点,以独立思考的态度,表达我的看法,或许我的理解有错误,可能我的观点并不合理,欢迎大家批评指正我的错误。后面我将以:表象——本质——我的思考 的基本流程与大家交流我的理解与观点。

实验代码地址:https://github.com/allhuo/deepin-java.git

本文实验代码:

模块名:chapter_001  

包名:com.lizhangjun.part01

二 我理解的反射

提起布偶猫,我们大致能想象到蓝色的眼睛,白灰的毛,长长的尾巴,四只爪子还会喵喵叫。反射如同我告诉告诉程序我是一只布偶猫,请准确描绘我的特征和行为。利用反射,我们可以通过类的名字,来知道这个类的功能,他有哪些函数。

三 表象

通过布偶猫的类名,我们获得布偶猫的实例,并访问它的方法。

实验结果:

四 深入

4.1 为什么每个类都会有getClass()方法?它有什么用途?

//获取布偶猫的类名

String className = ragDoll.getClass().getName();

 

 

getClass()会获得一个Class类型的实例,Java运行时,会为所有对象添加类型标识,这个标识关联着对象所属的类,而这个Class实例中维护了类型的基本信息,比如它是interface还是class,它有哪些变量,构造函数和其他功能函数等信息。特别地,在包下的类名,会包含包名信息com.yacoso.part01.RagDoll。

4.2 RagDoll与Class如何联系?

在自定义类RagDoll中,我们发现该类型的实例能调用getClass()方法获取Class对象,由于我们自定义的类默认继承了Object超类,而Object超类中定义了getClass()方法,因此RagDoll类中的getClass方法是从Object超类中继承而来,这样我们通过getClass()方法建立了自定义类与Class之间的纽带。

4.3 利用反射分析类的能力

    在java.lang.reflect包中有三个类Field、Method和Constructor分别用于描述类的域、方法和构造函数。对于Field类,里面有getType()方法可以获取域的类型,getName()获取域的名称,getModifiers()获取域的修饰符,如public或private等。对于Constructor类,里面有getDeclaredConstructors()可以获取类的所有构造函数,getName()获取构造函数的名称,getModifiers()获取构造函数的修饰符,getParameterTypes()获取构造函数的参数信息。对于Method类,里面有getMethods()获取类的方法,getReturnType()获取方法的返回类型,getModifiers()获取方法的修饰符,getParameterTypes()获取方法的传参信息。      getModifiers的方法,它将返回一个整型数值,用不同的数值描述public和static这样的修饰符使用状况,比如整型数值2对应的类型为private。

注:完整示例代码在本文对应源码包下的ReflectionTest类

public static void printConstructors(Class cl){

        Constructor[] constructors = cl.getDeclaredConstructors();

        for (Constructor c : constructors){
            String name = c.getName();
            System.out.print(" ");
            String s = Modifier.toString(c.getModifiers());
            if (s.length() > 0){
                System.out.print(s + " ");
            }
            System.out.print(name + "(");

            Class[] parameterTypes = c.getParameterTypes();
            for (int j = 0; j < parameterTypes.length; j++){
                if (j > 0){
                    System.out.print(", ");
                }
                System.out.print(parameterTypes[j].getName());
            }
            System.out.println(");");
        }

    }
public static void printMethods(Class cl){

        Method[] methods = cl.getMethods();

        for (Method m : methods){

            Class<?> returnType = m.getReturnType();
            String name = m.getName();

            System.out.print(" ");
            String s = Modifier.toString(m.getModifiers());
            if (s.length() > 0){
                System.out.print(s + " ");
            }
            System.out.print(returnType.getName() + " " + name + "(");

            Class<?>[] parameterTypes = m.getParameterTypes();
            for (int j = 0; j < parameterTypes.length; j++){
                if (j > 0){
                    System.out.print(", ");
                }
                System.out.print(parameterTypes[j].getName());
            }

            System.out.println(");");
        }

    }
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(" ");
            int modifiers = f.getModifiers();
            String s = Modifier.toString(f.getModifiers());
            if (s.length() > 0){
                System.out.print(s + " ");
            }
            System.out.println(type.getName() + " " + name + ";");
        }
    }

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值