黑马程序员_反射概述

------- 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;
  }
}
----------------------------------------------------------------------------------------------------------
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值
}
}
}
}

----------------------------------------------------------------------------------------------------------------------------------------
反射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();
           //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
}
}
----------------------------------------------------------------------------------------------------------------------------------------



------- android培训java培训、期待与您交流! ----------

详细请查看:http://edu.csdn.net/heima/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值