---------------------- 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培训、期待与您交流! -------------------------