---------------------- android培训 、 java培训 、 期待与您交流! ------------------
1、学习反射,首先要了解Class类
java类用于描述一类事物的共性,该类事物有什么属性,没有什么属性。
Class类描述的信息:类的名字,类的访问属性,类所属于的包名,字段名称的列表,实现的接口、方法名称的列表等等。
得到字节码对应的实例对象(Class类型)的三种方法:
1、类名.class 如:System.class;
2、对象.getClass() 如:new Date().getClass();
3、Class.forName("类名") 如:Class.forName("java.util.Date"); //做反射的时候一般用这种。
2、九个预定义的Class实例对象:
八个基本类型,加上void。即:Boolean, Character,Byte,Short,Integer,Long,Float,Double,Void.
int.class == Integer.TYPE。
查看是不是数组类型的Class实例对象用的是:Class.isArray().
总之,只要是在源程序中出现的类型,都有各自的Class实例对象。
3、反射的定义及其用法:
反射就是把java类中的各种成分映射成相应的java类。
-
构造方法的反射:Constructor类代表某个类中的一个构造方法:
得到某个类所有的构造方法----如:
Constructor [] constructor = Class.forName("java.lang.String").getConstructor();
得到某一个构造方法----如:
Constructor [] constructor = Class.forName("java.lang.String").getConstructor(StringBuffer.class);
用反射实现 new String(new StringBuffer("abc"));
如下: Constructor con = String.class.getConstructor(StringBuffer.class);
String str = (String)constructor.newInstance(new StringBuffer("abc"));
调用newInstance时要用到跟getConstructor中相同类型的实例对象。
也就是说上边第一句用了StringBuffer,第二句也必须是StringBuffer。
Class.newInstance()方法:
该方法内部先得到默认的构造方法,然后用该构造方法创建实例对象。
例子:String obj = (String)Class.forName("java.lang.String").newInstance();
- 成员变量的反射:Field类代表某个类中的一个成员变量。
public class ReflectPoint{
private int x;
public int y;
public ReflectPoint(int x, int y){
super();
this.x = x;
this.y = y;
}
}
public class ReflectTest{
public static void main(String[] args) throws Exception {
ReflectPoint pt1 = new ReflectPoint(3,5);
Field fieldY = pt1.getClass().getField("y");//fieldY不是对象身上的变量,而是类上的,
要用它去取某个对象上对应的值。
System.out.Println(fieldY.get(pt1)); //fieldY.get(pt1)取出pt1对象上变量的值。
fieldX.setAccessble(true); //暴力反射,不管是不是私有的,都可以取到。
Field fieldX = pt1.getClass().getDeclaredField("x");
System.out.Println(fieldX.get(pt1));
}
}
成员变量反射的综合案例:
public class ReflectString{
public String str1 = "ball";
public String str2 = "bass";
public String str3 = "this is a to babaa";
@Override
public String toString(){
return str1 + "..." + str2 + ";;;" + str3;
}
}
import java.lang.reflect.*;
public class ReflectTest{
public static void main(String[] args) throws Exception {
ReflectString rs = new ReflectString();
changeStringValue(rs);
System.out.println(rs);
}
private static void changeStringValue(Object obj) throws Exception{
Field[] fields = obj.getClass().getFields();
for(Field field : fields){
if(field.getType() == String.class){ //反射中用==比equals要好,因为字节码只有一个。
String oldValue = (String)field.get(obj);
String newValue = oldValue.replace('b','a');
field.set(obj, newValue);
}
}
}
}
输出为:aall...aass;;;this is a to aaaaa
- 成员方法的反射:Method类代表某个类中的一个成员方法。
得到类中的某一个方法:
例子:Method charAt = Class.forName("java.lang.String").getMethod("charAt", int.class);
调用方法:
通常方式:System.out.println(str.charAt(1));
反射方式:System.out.println(charAt.invoke(str,1));
如果传递给Method对象的invoke()方法的第一个参数为null,说明该Method对象对应的是一个静态方法!