Java反射机制

一、概念:

所谓反射,就是在程序运行期间,动态的获取类的属性,其中包括,属性(Field)、方法(Method)、构造器(constructor)。
1.1既然我提到了类,那我们先来看一看什么是类(或者说我们怎么能得到一个类对象)

package relfect;
public class WhatIsClass {
//这就是一个类(你new出来的,好像是废话),那么我们怎么获取这个类的Class对象呢?
Class clz;
void howTogetClass() throws ClassNotFoundException{
//方式一
clz=WhatIsClass.class.getClass();//这种方式在编译时获取的Class对象
//方式二 这个方式需要抛出一个ClassNotFound的异常
clz=Class.forName(“relfect.WhatIsClass”);//这种方式是在运行时获取的Class对象,由于参数为字符串,避免出错建议在properties文件中读取
}
}

1.2使用Class对象创建类的实例(与Constructor的运用)
WhatIsClass wic=(WhatIsClass) clz.newInstance();//获取WhatIsClass的实例
//这里需要注意的是,为保证newInstance()方法的正确调用,你的类对象中必须有默认的无参构造(public修饰)

1.2.1对于没有默认构造器的Class对象,创建实例的方法(这里用到的泛型有空会讲解)
对于使用构造器创建对象大家应该不陌生吧!
Constructor constructor=clz.getConstructor();//只能获取public访问级别的无参构造
constructor.setAccessible(true);//这个属性可以或略访问级别

Constructor<WhatIsClass> constructor=clz.getDeclaredConstructor();//可以或略访问级别来获取类对象的无参构造
WhatIsClass wic=constructor.newInstance();

1.2.3 如果构造器有参数呢?
比如
WhatIsClass 我们还沿用这个类,修改一下构造函数
private WhatIsClass (String arg1,String arg2,int arg3){};
那么对于这样的Class我们如何去创建实例呢?
Constructor constructor=clz.getConstructor(String.class,String.class,Integer.class);
constructor.setAccessible(true);//这个属性可以或略访问级别
Constructor constructor=clz.getDeclaredConstructor(String.class,String.class,Integer.class);//可以或略访问级别来获取类对象的无参构造
WhatIsClass wic=constructor.newInstance();

1.3 Field类中的属性
1.3.1 如何获取类中的属性
Field field=clz.getField(“username”);//假设我们要获取类中的一个username属性
field.setAccessible(true);//忽略属性的访问级别
String username=field.getName();

    //我们也可以这样
    Field[] fields = clz.getDeclaredFields();//忽略访问级别,获取所有对象组成的数组
    String [] fieldName=new String[fields.length];
    for (int i = 0; i < fields.length; i++) {
        fieldName[i]=fields[i].getName();
    }

1.3.2 既然我们已经获得了属性,那么我们是不是也能获得与之对应的get和set方法呢!
Field field=clz.getField(“username”);//假设我们要获取类中的一个username属性
field.setAccessible(true);//忽略属性的访问级别
String username=field.getName();

    PropertyDescriptor pd=new PropertyDescriptor(username, clz);
    Method setUsername=pd.getWriteMethod();
    setUsername.invoke(wic, "Hello World");

    //我们也可以这样
    Field[] fields = clz.getDeclaredFields();//忽略访问级别,获取所有对象组成的数组
    String [] fieldName=new String[fields.length];
    for (int i = 0; i < fields.length; i++) {
        fieldName[i]=fields[i].getName();
        pd=new PropertyDescriptor(fieldName[i], clz);
         Method writeSomeThing = pd.getReadMethod();//获得读方法
         writeSomeThing.invoke(wic, fieldName[i]);
    }

—当然我也也可以使用BeanInfo
BeanInfo beanInfo = Introspector.getBeanInfo(clz);
PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();
//剩下的代码同上

补充:由于反射的大部分方法都是见名知意的,就不一一列举了,
对于RTTI,大部分人知道的是instanceOf(); //判断导某某类的是否是某某类的导出类
但对于反射来说只能调用clz.isInstance();//来进行//这个方法并不存在基类的概念

这是我的第一篇博客,后续想到什么,有空就会去写,觉得我的文章对你撸码有帮助的,就请继续关注
要是那里说的不对,也请指出。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值