反射就是将java中的各种成分映射成相应的java类。我们把javaAPI里的所有类都抽象出来,就得到了构造方法(Constructor),成员变量(Field),成员函数(Method).反射的基石
反射的前提是得到字节码,每一种数据类型都对应着一份字节码,当new对象时,都是在对这份字节码的复制。比如:String类型对应的字节码就是String.class。获得字节码的三种获取方式
1.通过java类来获取
类名.class 例:int[].class;
2.通过对象来获取
对象.getClass() 例:String str="123";str.getClass();
3.通过类名称来获取(通常是相应的类或者对象都没有被加载到内存)
Class.forName(类名称); 例:Class.forName("java.util.Date");构造函数的反射(Constructor)
1.先得到相应的字节码
Class cls=string.lass();
2.通过字节码来获取构造函数,这里可以指定参数。
Constructor con=cls.getConstructor(StringBuffer.class);//这里的参数代表传入构造函数的参数类型
3.通过构造函数来创建实例
con.newInstance(new StringBuffer("abc"));//这里的参数是传入到构造函数的参数值
总结:这里反射实现的等同于String str=new String(new StringBuffer("abc"));
成员变量的反射(Field)
1.先得到相应的字节码
reflectPoint rPoint=new reflectPoint(3, 5);
Class pointClass=reflectPoint.class;
2.通过字节码指定要获取的哪个成员变量,返回Field对象的类成员变量Fieldx,并通过Field对象获取相应对象的此成员变量的值
Field Fieldx=pointClass.getField("x");
int x=(int)Fieldx.get(rPoint);
3.如果指定对象的成员变量为私有,如y,要使用暴力反射来得到相应的值
Field Fieldy=pointClass.getDeclaredField("y"); //先获取Field对应的类成员变量 ,使用getDeclaredField方法
Fieldy.setAccessible(true); //再设置field类成员变量的权限为可访问
int y=Fieldy.getInt(rPoint); //使用类成员变量得到相应的对象的该成员变量的值
package reflect;
public class reflectPoint {
public int x;
private int y;
public String str1="wangcong";
public String str2="wanghuan";
public reflectPoint(int x, int y) {
super();
this.x = x;
this.y = y;
}
@Override
public String toString()
{
return str1+":"+str2;
}
}
成员方法的反射Method
1.先得到字节码
String str="abc";
Class cls=str.getClass();
2.通过字节码得到类成员方法
Method charAtMethod=cls.getMethod("charAt",int.class);//这里的chatAt是String的方法,int.class是chatAt的参数类型。如chatAt(1);
3.用类成员方法去调用对象,以及传值
charAtMethod.invoke(str,1);//str是String的对象,1代表charAt的参数charAt(1);
下面的例子是用方法反射来调用main方法
import java.lang.reflect.*;
class MethodDemo
{
public static void main(String[] args) throws Exception
{
//在运行的时候传入类名
String str=args[0];
System.out.println(str);
Method startingClassMethod=Class.forName(str).getMethod("main", String[].class);
startingClassMethod.invoke(null, (Object)new String[]{"111","222","333"});
}
}
class testArguments
{
public static void main(String[] args)
{
for(String arg:args)
{
System.out.println(arg);
}
}
}
下面的小例子是用反射的方法去创建集合对象
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.Collection;
import java.util.Properties;
public class HashSetDemo {
/**
* @param args
*/
public static void main(String[] args) throws Exception {
InputStream inputStream=new FileInputStream("E:\\Android\\WorkSpace\\StudyJava\\src\\reflect\\conn.Properties");
Properties properties=new Properties();
properties.load(inputStream);inputStream.close();
String ClassName=properties.getProperty("ClassName");
System.out.println(ClassName);
Collection collection=(Collection)Class.forName(ClassName).newInstance();
reflectPoint rp1=new reflectPoint(3, 3);
reflectPoint rp2=new reflectPoint(5, 5);
reflectPoint rp3=new reflectPoint(3, 3);
collection.add(rp1);
collection.add(rp2);
collection.add(rp3);
System.out.println(collection.size());
}
}
conn.Properties的信息
ClassName=java.util.ArrayList