------- android培训、java培训、期待与您交流! ----------
一、Constructor类
Constructor[] cons = String.class.getConstructors(); //得到String类的所有的构造方法
Constructor con = String.class.getConstructor(StringBuffer.class); //得到StringBuffer类的一个的构造方法
String str = (String)con.newInstance(new StringBuffer("abc")); //实例化Constructor对象
这里需要说明一下,
1、想要得到哪个构造方法的Constructor类就在getConstructor()方法里写上想得到的构造方法所传的参数类型的字节码;
2、在将Constructor进行实例化的时候的newInstance()方法中写的是这个构造函数所传参数的对象
3、最后需要将实例化对象强制转换成String类型,因为实例化之后返回类型是Object
String.class.newInstance();
最后也可以直接用过String类的字节码直接通过newInstance()方法,得到String的无参构造方法,然后通过无参的构造方法创建String的实例化对象,这个最后得到的也是Object,所以也要进行强制转换的哦
二、Field类
先写一个ReflectField类,记录两个变量,一个私有的x和一个共有的y,并建立有参的构造方法
private int x;
public int y;
public ReflectField(int x, int y) {
super();
this.x = x;
this.y = y;
}
ReflectField rf1 = new ReflectField(6,8);
//Field[] fields = rf1.getClass().getFields();//得到所有的变量放入到Field数组
Field fieldY = rf1.getClass().getField("y");
System.out.println(fieldY.get(rf1));
Field fieldX = rf1.getClass().getDeclaredField("x");
fieldX.setAccessible(true); //暴力反射
System.out.println(fieldX.get(rp1));
需要注意的
1、得到ReflectField类的字节码后getField()方法这里需要写的是变量名
2、只是把y变量赋值给了fieldY,如果想得到y的值那么还要确定是哪个对象的里的y,所以fieldY的get()方法这里写的就是 ReflectField对象
3、由于x是私有的,所以如果想访问到变量x,就要用getDeclaredField()方法,将x变量赋值给fieldX;如果想打印x变量,则需要设置一个属性setAccessible(true)后就可以正常打印了
下边做一个练习,将一个对象里所有的String类型的变量所对应的字符串,将b改成Z
public static void ChangeValue(Object obj) {
Field[] fds = obj.getClass().getFields();
for(Field fd: fds)
{
try {
if (fd.getType() == String.class) {
String oldstr = (String) fd.get(obj);
String newstr = oldstr.replace('b', 'Z');
fd.set(obj, newstr);
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
注意:
1、field.getType()获取field这个变量的类型
2、如果类中的成员变量没有权限修饰,那么getFields()就需要变成getDeclaredFields();
三、Medthod类
String str1 = "abc";
Method methodCharAt = String.class.getMethod("charAt", int.class);//把String的charAt()方法赋给methodCharAt变量
System.out.println(methodCharAt.invoke(str1, 1));//调用methodCharAt的invoke()方法,打印结果为b
System.out.println(methodCharAt.invoke(str1, new Object[]{1}));//jdk1.4之前的书写方式,打印结果也是b
注意:
1、这里getMethod(),这里第一个是这个方法的名字;后边是这个方法传的参数
2、invoke()这里的str1是对象,后边的1是要给charAt这个方法传的参数(即,调用str1对象的chartAt(1)方法)
3、如果invoke()方法的第一个参数是null,那么这个charAt()方法不需要通过对象就可以调用,由此可以得出这个方法是静态方法。
四、数组的应用
Class cls = Class.forName("java.lang.String");
Object arr = Array.newInstance(cls, 10); //实例化一个长度为10的String类型数组
Array.set(arr, 5, "this is a test"); //将数组的第五个位置替换成"this is a test"
String s = (String) Array.get(arr, 5); //得到数组的第五个位置,并强制转换成String类型
System.out.println(s);
Class cla = obj.getClass();
if(cla.isArray()){ //判断cla是不是数组类型
for(int i=0;i<Array.getLength(obj);i++){
System.out.println(Array.get(obj, i));
}
}else{
System.out.println(obj);
}
判断如果是数组类型就挨个打印数组里的元素,如果不是数组类型就直接打印