黑马程序员——反射

------ android培训java培训、期待与您交流! ---------- 

 

反射是Java中最重要的概念之一,它可以构成各个框架,能快速的搭建需要的类。所以,学Java就必须掌握好反射的应用。

Java程序中各个Java类属于同一类事物,描述这类事物的Java类名就是Class。Class类是反射的基石,只有通过Class类才能实现反射的功能。

获取Class对象的方式

//通过创建对象获取字节码对象
1,Person p = new Person();
Class cls1 = p.getClass();
//任意数据类型都具备一个class静态属性
2,Class cls2 = Person.class;
//按类名作为字符串传递给Class类中的static方法forName即可
3,Class cls3 = Class.forName("java.lang.Person");

需要注意的是:

int.class == Integer.TYPE

数组类型的Class不是基本数据类型,Class.isArray()

 

反射:就是把Java类中的各种成分映射成相应的Java类,然后对这些类进行操作。

如:Contructor,Field,Method,Package等

 

Constructor类:(构造函数类)

 通过反射的方式来构造一个函数,实现方式代码:new String(new StringBuffer("abc"));

 

Constructor<String> constructor1 =   
                String.class.getConstructor(StringBuilder.class);  
        String str1 = constructor1.newInstance(new StringBuilder("abc"));     
        System.out.println(str1.charAt(2));  


 先用Class类调用getConstructor(参数.class)方法得到Constructor类,再用newInstance("参数")的方法来创建一个这个类的对象。

 Class类的newInstance()方法是使用该类无参的构造函数创建对象, 如果一个类没有无参的构造函数, 就不能这样创建了  

 

 Field
  Class.getField(String)方法可以获取类中的指定字段(可见的),如果是私有的可以用getDeclaedField("name")方法获取

 如果是私有的需要先调用setAccessible(true)设置访问权限,用获取的指定的字段调用get(obj)可以获取指定对象中该字段的值
 通过set(obj, newValue)方法可以设置指定对象上该字段的值

//这了是一个类,其中有两个变量 private x , public y   
ReflectPoint pt1 = new ReflectPoint(3,5);  
//得到public变量的方法   
Field feildY = pt1.getClass().getField("y");  
System.out.println(feildY.get(pt1));  
//得到private变量的方法   
Field feildX = pt1.getClass().getDeclaredField("x");  
//必须强制设置可获取   
feildX.setAccessible(true);  
System.out.println(feildX.get(pt1));


 

  Method
 只需要知道方法的名称即可。 Class.getMethod(String, Class...) 和 Class.getDeclaredMethod(String, Class...)方法可以获取类中的指定方法
  调用invoke(Object, Object...)可以调用该方法

  

//得到String类中的charAt方法,反射调用之   
Method charAt = String.class.getMethod("charAt", int.class);  
System.out.println(charAt.invoke(str, 1)); 

  如果传递给Method对象的invoke()方法的第一个参数为null,那么该Method对象对应的是一个静态方法

 

 数组反射:

通过Array类中方法来完成。

将数组转化成一个Object类,传递进去。通过isArray()方法确定其是否为数组,用Array.get(obj,index)来调用。

private static void printObject(Object obj) {  
        if (obj.getClass().isArray()) {  
            int len = Array.getLength(obj);  
            for (int i = 0; i < len; i++) {  
                System.out.println(Array.get(obj, i));  
            }   
        }else {  
            System.out.println(obj);  
        }  


 

 内省

JavaBean是一种特殊的Java类,主要用于传递数据信息。这种java类中的方法主要用于访问私有的字段,且方法名符合某种命名规则

JDK中提供了对JavaBean进行操作地API,这些API称为内省。

内省就是反射过程中,因为要设置、获取类中的成员变量时,而通过getField方法实现代码太过于复杂。仅仅是设置、获取两个操作就要写上很多代码,不利于工作,从而简化内容而出现了内省机制。

通过规定设置用setXXX方法,获取用getXXX方法来统一命名,这样就可以把getField中复杂的代码封装在内部,对外提供一些简单的方法即可实现设置、获取操作。

 

下面写出2种最简单的用反射获取到get和set方法的例子:

//通过使用PropertyDescriptor类,接收成员变量的名称,该类的Class对象   
 PropertyDescriptor pd1 = new PropertyDescriptor(propertyName,pt1.getClass());  
//调用PropertyDescriptor类中的getWriteMethod()方法来得到设置方法   
//调用getReadMethod()来得到获取方法   
  Method methodSetX = pd1.getWriteMethod();  
  methodSetX.invoke(pt1, setVal); 


BreanUtils.jar包和Logging.jar包把这些方法也封装成对象,只要传入参数就可以直接用调用set、get方法,

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值