黑马程序员-----反射的学习日志

 

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

 

 

Class类

 

Java类用于描述一类事物的共性。该类事物有什么属性,没有什么属性,至于这个属性的值是什么,则是由这个类的实例对象来确

定的。不同的实例对象有不同的属性值。Java程序中的各个java类,它们是否属于同一类事物,是不是可以用一个类来描述这类事

物呢?java程序中的各个Java类属于同一类事物,描述这事物的Java类名就是Class。

通常获取Class类的方法:

eg: String str="xyz";

1.Class cls=str.getClass();

2.Class cls=String.class;

3.Class cls=Class.forName("java.lang.String");

 

-----------------------------------------------------------------------------

 

反射:

 

正常情况下必须先有类,再有对象,反射的过程是通过对象,找到其所在的类。利用这些对象进行一些操作。

也就是说反射把Java类中的各个成分映射成相应的java类的对象。一个类中的每个成员都可以用相应的反射API类的一个实例对象来表示。如构造方法可以用一个Constructor对象来表

示,成员变量可以用Filed对象来表示,成员方法可以用Method对象来表示,包可以用Package对象来表示。

 


 

Constructor类

Constructor类代表某个类中的一个构造方法,
1.得到某个类所有的构造方法:
Constructor[] constructors=Class.forName("java.lang.String").getConstructor();
2.得到某一个构造方法:  
Constructor constructor=Class.forName("java.lang.String").getConstructor(StringBuffer.class);

例子:Sring obj=(String)Class.forName("java.langString").newInstance();
该方法内部先得到默认的构造方法,然后用该构造方法创建实例对象。
该方法内部的具体代码是怎么样写的呢?用到了缓存机制来保存默认构造方法的实例对象。
创建实例对象:
1.通常方式:String str=new String(new StringBuffer("abc"));
2.反射方式:String str=(String)constructor.newInstance(new StringBuffer("abc"));
根据参数的类型和个数来确定相应的构造函数,而参数的类型则是用Class实例化得到对象的类型字节码。

 

 

Field类

Class对象的getField方法

需要传递变量的变量名作为参数,FieldX代表着某个类中的成员变量的属性,而不是具体到这个对象中的值。

通过Field类的get()方法来获得某个对象中相应字段的值,需要指定要获取字段值的对象。

如Field fieldX=obj.getClass().getField(“x”);//得到类的Field对象

fieldX.get(obj);//得到某个对象的x字段的值。

若成员函数中存在私有函数则可以暴力访问:

Field fieldX=obj.getClass().getDeclaredField(“x”);//得到声明的字段

fieldX.setAccessible(true);//将这个字段设置为可以访问

fieldX.get(obj);// 这时就可以得到某个对象的x字段的值

 

 

Method类

Class对象的getMethod方法

需要传递方法名和参数类型作为参数。

通过Method类的invoke方法来执行方法,需要指定执行方法的对象,如果是静态方法,就指定对象为null

调用方法:

Method charAt=Class.forName(java.lang.String).getMethod(“charAt”,int.class);        

charAt.invoke(str,1);

 

jdk 1.4和jdk1.5的invoke方法的区别

jdk1.5:public Object invoke(Object obj,Object… args)

jdk1.4:public Object invoke(Object obj,Object[] args)

即按照jdk1.4的语法如果传递一个数组作为参数的话,并不会把这个数组当做一个参数,而是会将其拆包,当做多个参数来使用,而jdk1.5的语法必须兼容jdk1.4的语法,那么如果真要传递一个数组作为参数又该怎么办呢,如调用main方法
解决方法:
1.  mainMethod.invoke(null,new Object[]{new String[]{“xxx”}});
将数组参数放在一个数组中,这样就可以得到这个数组参数。
2.  mainMethod.invoke(null,(Object){new String[]{“xxx”}});
将数组参数强制类型转换为Object,意思是不要把我当做一个数组来看待,这样就不会将其拆分为若干个参数了。

 

 

数组的反射:

 

具有相同维数和元素类型的数组属于同一个类型,即具有相同的Class实例对象。

数组的父类是Object,代表数组的Class实例对象的getSuperClass()方法返回的父类为Objec类对应的Class

object.getClass().getSuperclass().getName();

基本类型的数组可以被当做Object类型使用,不能当做Object[]类型使用

非基本类型的一维数组,既可以当做Object类型使用,又可以当做Object[]类型使用。(在JDK1.4方法ArrarsList中数组对象当做Object[]操作,此时int[]被当做一个对象object,内部数组元素不能输出,而String[]则可以)

 
注意:object是用hashCode()的方法返回每个Java的哈希码,而哈希码的分段存储和同一区域不存储相同元素,致使可能不会输出数组中所有元素的值,这时对数组进行Arrays的静态方法asList将数组转化为List就很方便的遍历和输出所有数组元素。

eg:


public class ArrayReflectTest { 
 
        String[] str=new String[]{"heng","heng","ha","hei"}; 
        Prints(str);  
        Prints("miximixi");  

}

public static void Prints(Object obj) {  
            Class clas=obj.getClass(); 
            if(clas.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); 
            } 
        } 
}

 

 

 

 

 

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

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值