浅谈java的反射机制,只是有助于去理解这一机制。,浅谈java
分享于 点击 43263 次 点评:85
浅谈java的反射机制,只是有助于去理解这一机制。,浅谈java
首先,在了解java的反射的时候,我们应该先提出几个问题,
第一,什么是java的反射机制?
第二,java反射机制的功能是什么?
第三,为什么要用java的反射机制?
第四,java的反射机制是如何实现的,实现的过程是什么样子的?
通过这四个问题,我们一点点如了解java的反射机制。
第一个问题:
java的反射机制是在运行状态,对任意一个类,能够知道这个类的所有属性和方法,对任意一个对象都能够调用它的任意方法和属性。这种动态调获取信息以及动态调用对象的方法功能就是java语言的反射机制。或者说就是加载一个运行时才知道的类以及他的完整内部结构。举个小栗子。
package com.sohu.action;
public class TestModel {
String name="我是成员变量!";
/**
* 构造函数
*/
public TestModel(){
System.out.println("----我是构造函数!----");
}
/**
* 静态代码块
*/
static{
System.out.println("---我是静态代码块-----");
}
{
System.out.println("----我是非静态代码块----");
}
public void method(){
System.out.println("---我是局部方法---");
}
}
编写测试类:
public class Test3 {
public static void main(String[] args) {
try {
//测试类名.class
Class testModel=TestModel.class;
System.out.println("获取包名===>"+testModel.getPackage());
System.out.println("获取类的全路径===>"+testModel.getName());
System.out.println("获取类名===>"+testModel.getSimpleName());
Method[] methods = testModel.getMethods();
for(Method method:methods){
System.out.println("===获取方法===="+method.getName());
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
上面的输出如下:
获取包名===>package com.sohu.action
获取类的全路径===>com.sohu.action.TestModel
获取类名===>TestModel
===获取方法====method
===获取方法====wait
===获取方法====wait
===获取方法====wait
===获取方法====hashCode
===获取方法====getClass
===获取方法====equals
===获取方法====toString
===获取方法====notify
===获取方法====notifyAll
这里的(类名).class就是反射。这里获取Class对象,还有两种方法:new (类).getClass()和Class.forName("类的全路径"),这个以后再细说。
通过上面的例子,我们可以看出,java的反射机制是可以获取运行时才知的类的方法和属性,其他的测试大家可以自己去做一下。这里的
现在来看第二个问题:
java反射提供的功能:
1.在运行时判断任意一个对象所属的类;
2.在运行时构建任意一个类的对象;
3.在运行时判断任意一个类所具有的成员变量和方法;
4.在运行时调用任意一个对象的方法;
以上四个在参考上面的例子进行理解;要注意,这四个都是在运行时而不是编译时进行的,也就是说在运行时不知道哪个类,通过反射实现了我们想要的。
5.生成动态代理。
然后我们来看,为什么要用反射机制;
首先,java的反射可以使代码更加灵活,更加容易实现面向对象。
期次就是java反射可以解藕。
对于最后一个问题,也还是浅显的用例子来说明一下,对于java的反射机制也只能起到一定理解作用,在深入还需要更加努力的去了解。
例如有这样的情况,我们有多个实体类,每个实体类中的属性都不一样,不会重复,我们要获取其中的某些属性,这些属性不在同一个实体类中,该如何去实现。直接上代码
package com.sohu.action;
import java.lang.reflect.Method;
import java.util.List;
/**
* 封装联合实体类的方法
* 利用java的反射类method
* @author HBL1
*
*/
public class ModelUtils {
//需要一个List放置实体类
List<Object> list=null;
/**
* 构造函数,进行赋值
* @param list
*/
public ModelUtils(List<Object> list){
this.list=list;
}
/**
* 获取属性的值
* @param fName 获取联合实体类的属性的名称
* @return
*/
public <T> T getValue(String fName){
//组装方法名,这步是为了在调用此方法时直接进行参数传递就行,不需要传方法名称
String methodName="get"+fName.substring(0,1).toUpperCase()+fName.substring(1);
//获取方法名所在的实体类
for(Object o:list){
try {
//查找方法,查找还有一个无参数的方法,单能传方法就尽量传,提高反射效率
Method method = o.getClass().getMethod(methodName);
//判断方法是否存在
if(method!=null){
//由于invoke返回的是Object类型,因此要强制转换成T类型
return (T)method.invoke(o);
}
} catch (Exception e) {
}
}
return null;
}
public <T> void setValue(String fName,T value,Class<T> type){
String methodName="set"+fName.substring(0,1).toUpperCase()+fName.substring(1);
for(Object o:list){
try {
//查找方法
Method method = o.getClass().getMethod(methodName,type);
if(method!=null){
method.invoke(o, value);
return;
}
} catch (Exception e) {
}
}
}
}
然后我们测试一下利用反射封装的类如何实现我们想要的,在这里实体类就不上传了。
package com.sohu.action;
import java.util.ArrayList;
import java.util.List;
import utils.system;
import flex.cc.baseInfo.model.GBankaccount;
import flex.cc.baseInfo.model.GInsurer;
public class Test2 {
public static void main(String[] args) {
List<Object> list =new ArrayList<Object>();
list.add(new GBankaccount());
list.add(new GInsurer());
FieldsUtils fieldsUtils=new FieldsUtils(list);
String name="fparentid";//这个是你要获取的属性值
String value="我是测试数据";
fieldsUtils.setValue(name, value);
System.out.println(fieldsUtils.getValue(name));
}
}
打印的结果如下:
我是测试数据
获取到了我们想要的数据。对于java反射还在进一步理解中,有许多不足之处还请多指教,
相关文章
- 暂无相关文章
用户点评