Java的反射好不好玩??

假如初识java或者只是玩一个小project,可能觉的反射用处不大,毕竟没有可用之处。但随着project越来越大,那反射就解决了好多key problems。首先我觉的反射这个名字太直白了,直接将reflect直译过来,我觉得应该叫内审或者自我剖析比较好,因为毕竟目的是要去了解一个类内部的一些属性或者方法嘛。

先举个栗子:

假如我的application需要和客户端交互(也是我碰到的真实栗子),客户的request里可能有各种各样的对我程序内交易类的访问,可能访问程序的模块A、模块B……..按照像我一样的小菜来说,可能首先想到的是:哦,把各种访问的可能性都考虑进来吧,于是:

switch(case){
        case A :
            doA();
            break;
        case B :
            doB();
            break;
        case C :
            doB();
            break;
        case D :
            doB();
            break;
        ...
        .....
        }

我承认假如我不接触反射我会这样去做。

回过头来分析一下:这个不确定性就是不知道客户会访问哪个模块,即无法在编译期就确定,那么一个思路就是:好吧,那就交给运行期去确定用户访问模块吧。我们知道:当new一个新对象时首先先将类信息加载到方法区(假如首次加载)然后再将类的成员变量在堆内存上分配空间(这里不懂得建议去看一下thinking in java喽),所以反射的话也是遵循这个思路:
Class.forName(request.getModule())——–forName()这个静态方法意思是根据后边的String参数即类名,将其new一个class对象,注意得到的是一个class对象,而不是实例哈,此时就可以对该对象调用一系列方法,如getMethods()、getConstructors()等等来获取该类的方法和构造器等等(因为这些都属于类的常量了,都是贮存在方法区不变的,不懂得看Tinking in java撒),当然也可以根据该类对象去new一个实例了,像我的业务就用到了newInstance(),于是乎,上边的switch就完全可以改成:

Class.forName(Request.getModule()).newInstance();
即根据用户request里的访问模块需求来new出模块实例

后续操作当然就是根据new出的实例去进行一系列方法调用…..操作了
这样是不是方便了很多?

最后给大家一个有趣的东东:假如忘记了一个jdk某类的一些信息(有哪些方法了)而又不想去查API文档,那就用反射吧:

package jsoup;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;

public class Reflect {
    public static void main(String[] args){
        if(args.length<0){
            System.exit(0);
        }
        if(args.length==1){
            try {
                Class  obj = Class.forName(args[0]);

                System.out.println("类名称为:" + obj.getName());
                Method[] method = obj.getMethods();
                for(Method m : method)
                    System.out.println("类内的方法有:"+ m);

                Constructor[] con = obj.getConstructors();
                for(Constructor c : con)
                    System.out.println("类的构造器为:" + c);

            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }

        }
    }
}

在Eclipse运行的时候将arguments改成你需要查询的类的名称,注意是全称哦,for example:java.lang.String
或者在本地编译—运行 javac Reflect.java——-java Reflect java.lang.String

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Frank Lin

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值