浅谈Java的反射(一) 构造方法反射调用

“程序运行时,允许改变程序结构或变量类型,这种语言称为动态语言”。从这个观点看,Perl,Python,Ruby是动态语言,C++,Java,C#不是动态语言。但是JAVA有着一个非常突出的动态相关机制:Reflection,用在Java身上指的是我们可以于运行时加载、探知、使用编译期间完全未知的classes。换句话说,Java程序可以加载一个运行时才得知名称的class,获悉其完整构造(但不包括methods定义),并生成其对象实体、或对其fields设值、或唤起其methods。
以上就是Java反射的一个介绍,很多配置型框架的底层,也都用到了反射的原理来实现动态的加载类,而你只需要配置好相应的类全名。但如何使用java 来实现他的反射呢?
其实在java中,有三种方法能够获得一个类的字节码:
三种方式加载类获得类的字节码Class clazz
1. Class.forName("classfullnamne");
2. new classname().getClass();
3. calssname.class

而获得了类的字节码,我们就能够获得这个类的构造函数,方法,成员变量。继而动态的操纵这个类。第一种方法就是用反射的概念来获得了一个类的字节码。
例如我在配置文件中,找到了一个com.test.User的字符串,我知道这句是我需要动态加载的类全名。我只需要使用Class的一个静态方法:
Class clazz = Class.forName("com.test.User");


而我们获得了字节码,就可通过下面的代码来获取他的实例:
User user = (User)clazz.newInstance();  (在此我们假设知道实例化的类是个User类而将其强转)

当然,我们还可以通过以下代码来获取这个类的构造方法:
Constructor con = clazz.getConstructor();  (这个方法没有参数的时候,是调用无参的构造方法。)
Constructor con = clazz.getConstructor(String.class, int.class) (这个方法获得了一个带有两个参数的构造方法,且第一个参数是String类型,第二个参数是int类型的构造方法)

当获取了构造方法,我们就可以使用获取的构造方法实例化对象了,代码如下:
User user = (User)con.newInstance();  (对,你没有看错,构造方法也有一个叫做newInstance()的方法,用以实例化对象,当前是调用无参的构造方法,实现原理跟之前我们直接用字节码获取他的实例一样。)
User user = (User) con.newInstance("Tang Yu",29); (对应上面第二个带参数的构造方法,传入相应的两个参数,第一个是String类型,第二个是int类型)

当然,如果我们的够造方法是私有的,我们就无法通过clazz.getConstructor()这一方法来获取到他了。如果获取对象的私有构造方法呢?众所周知,Java的私有方法只能在对象本身内部调用,但是java通过反射也给我们留了一个后门,让我们在外部也能调用他的私有方法,包括私有构造方法。这就是暴力反射,这时候,首先在我们获得我们需要写以下代码:
Constructor c = clazz.getDeclaredConstructor(); (大家注意,不是之前那个获得构造函数的方法了。)
c.setAccessible(true); (使用这句代码,使进入该私有构造方法可能。切记,如果没有这句代码,会报错,说无法在外部访问private的方法)

获得了构造方法,并且也设置了他的访问权限公开,之后的就能正常调用该方法了。
至此,我们使用反射的原理,动态的调用类的构造方法并产生实例就实现了。
下节我将研究如何使用反射动态的调用该类中的普通方法。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值