------- android培训、java培训、期待与您交流! ----------
反射的基石 -->class类
· Java程序中的各个Java类属于同一个事物,描述这类事物的Java类名就是Class。
字节码文件是经过编译器预处理过的一种文件,是JAVA的执行文件存在形式,它本身是二进制文件,
但是不可以被系统直接执行,而是需要虚拟机解释执行。
获得字节码的3种不同方式:
·类名.class
·对象.getClass()
·Class.forname("类名")
九种预定义Class实例对象:
byte short int long float double char boolean void
反射就是把Java类中的各种成分映射成相应的Java类。例如,一个Java类中用一个Class类的对象来表示,
一个类中的组成部分:成员变量,方法,构造方法,包等等信息也用一个个的Java类来表示,就像汽车是一个
类,汽车中的发动机,变速箱等等也是一个类。表示java类的Class类显然要提供一系列的方法,来获得其
中的变量,方法,构造方法,修饰符,包等信息,这些信息就是用相应的实例对象来表示的。
一个类中的每个成员都可以用相应的反射API类中的一个实例对象来表示,通过Class类的方法可以得到这些
实例对象后,得到这些实例对象后有什么用呢?怎么用正是学习和应用反射的要点。
Constractor类
·Constractor类代表某个类的一个构造方法得到某个类所有的构造方法:
Contructor constructors[]=Class.forName("java.lang.String").getConstructors();
得到某一个构造方法:
Constractor constractor=Class.forName("java.lang.String").getConstractor(StringBuffer.class);
Filed类
·Field类代表某个类中的一个变量成员
Method类
Method类代表某个方法的一个成员方法
调用方法:
通常方式:System.out.println(str.charAt(1));
反射方式:System.out.println(charAt.invoke(str,1));
如果传递给Method对象的invoke()方法的第一个参数为null,说明该Method对象对应的是一个静态方法。
jdk.1.4和jdk1.5的invoke方法区别:
jdk1.5:public Object invoke(Obejct obj,Object...args)
jdk1.4:public Object invoke(Objecct obj,Object [] args)即按jdk1.4的语法,需要将一个数组作为参数传
递给invoke方法时,数组中的每一个元素分别对应被调用方法的一个参数,所以,调用charAt方法的代码也
可以用jdk1.4的方法改写为charAt.invoke("str",new Object[]{1})形式
----------------------------------------------------------------------------------------------------------------------------------------
public class ReflectPoint {
private int x;
public int y;
public String str1="aaa";
public String str2="bbb";
public ReflectPoint(int x,int y){
super();
this.x=x;
this.y=y;
}
public String toString(){ //覆盖toString()方法
return str1+":"+str2;
}
}
private int x;
public int y;
public String str1="aaa";
public String str2="bbb";
public ReflectPoint(int x,int y){
super();
this.x=x;
this.y=y;
}
public String toString(){ //覆盖toString()方法
return str1+":"+str2;
}
}
----------------------------------------------------------------------------------------------------------
public class ReflectDemo02 {
public static void main(String[] args) throws Exception {
ReflectPoint pt1=new ReflectPoint(3,5); //创建一个ReflectPoint 对象
changeStringValue(pt1);
System.out.println(pt1); //bbb:bbb
}
private static void changeStringValue(Object obj) throws Exception {
Field [] fields=obj.getClass().getFields(); //通过字节码获得getFields()方法
for(Field field:fields){ //迭代
if(field.getType()==String.class){ //查找String类型的变量
String oldValue=(String)field.get(obj); //取得相应的值
String newValue=oldValue.replace("a","b"); //替换字符
field.set(obj, newValue); / /对obj进行set值
}
}
}
}
public static void main(String[] args) throws Exception {
ReflectPoint pt1=new ReflectPoint(3,5); //创建一个ReflectPoint 对象
changeStringValue(pt1);
System.out.println(pt1); //bbb:bbb
}
private static void changeStringValue(Object obj) throws Exception {
Field [] fields=obj.getClass().getFields(); //通过字节码获得getFields()方法
for(Field field:fields){ //迭代
if(field.getType()==String.class){ //查找String类型的变量
String oldValue=(String)field.get(obj); //取得相应的值
String newValue=oldValue.replace("a","b"); //替换字符
field.set(obj, newValue); / /对obj进行set值
}
}
}
}
----------------------------------------------------------------------------------------------------------------------------------------
反射Main方法
问题:
mainMethod.invoke(null,new Object[]{new String[]{"xxx"}}),javac只把它当作jdk1.4的语法进行理解,而不把
它当作jdk1.5d的语法解释,因此出现参数类型不对的问题。
解决办法:
mainMethod.invoke(null,(Object)new Object[]{new String[]{"xxx"}}),编译器会做特殊处理,编译时不把参数当
作数组看待,也就不会把数组打散成若干个参数了。
数组的反射:
·相同维数和元素类型的数组属于同一个类型,即具有相同的Classlass()方法返回的父类为Object类对应的Class
·基本类型的一维数组可以当作Object内心使用,不能当作Object[]类型使用;非基本类型的一维数组,既可以当做
Object类型使用,又可以当作Object[]类型使用ArrayList.asList()方法处理int[]和String{}时的差异
反射的作用 --> 实现框架功能
·框架与框架要解决的核心问题
我做房子卖给用户住,由用户安装门窗和空调,我做的房子就是框架,用户需要使用我的框架,把门窗插进我提供
的框架中。框架与工具类有区别,工具类被用户的类调用,而框架则是调用用户提供的类。
框架要解决的核心问题
我在建房子时,用户还没建窗子,以后我写的框架如何调用用户的类呢?因为在写程序时无法知道要调用的类名,
所以,在程序中无法直接new某个实例对象了,而要用反射方式来做。
----------------------------------------------------------------------------------------------------------------------------------------
综合案例:这是一个简单的反射案例
----------------------------------------------------------------------------------
配置文件
className=java.util.ArrayList
----------------------------------------------------------------------------------
public class ReflectDemo06 {
public static void main(String[] args) throws Exception {
InputStream ips=new FileInputStream("config.properties"); //创建一个流
Properties props=new Properties();
props.load(ips); / /加载文件
ips.close(); //释放资源
String className=props.getProperty("className");
Collection collections=(Collection)Class.forName(className).newInstance();
public static void main(String[] args) throws Exception {
InputStream ips=new FileInputStream("config.properties"); //创建一个流
Properties props=new Properties();
props.load(ips); / /加载文件
ips.close(); //释放资源
String className=props.getProperty("className");
Collection collections=(Collection)Class.forName(className).newInstance();
//new Collection对象 把要用的类放在配置文件中 在源程序里不用出现这个类的名字
ReflectPoint pt1=new ReflectPoint(3,1);
ReflectPoint pt2=new ReflectPoint(3,2);
ReflectPoint pt3=new ReflectPoint(3,3);
collections.add(pt1);
collections.add(pt2);
collections.add(pt3);
System.out.println(collections.size()); //3
}
}
ReflectPoint pt1=new ReflectPoint(3,1);
ReflectPoint pt2=new ReflectPoint(3,2);
ReflectPoint pt3=new ReflectPoint(3,3);
collections.add(pt1);
collections.add(pt2);
collections.add(pt3);
System.out.println(collections.size()); //3
}
}
----------------------------------------------------------------------------------------------------------------------------------------
------- android培训、java培训、期待与您交流! ----------
详细请查看:http://edu.csdn.net/heima/