黑马程序员_java的反射

------- <a href="http://www.itheima.com" target="blank">android培训</a>、<a href="http://www.itheima.com" target="blank">java培训</a>、期待与您交流! ----------

一、反射的作用:

(1)反射的主要作用:在做框架的时候随处可见。

    在学习反射的时候,我们常常使用到的java api.

    1:Class:代表一个类

    2:Method:代表类中的方法;

    3:Constructor:代表一个构造方法

    4.Array:提供一个动态创建数组的类,可以访问数组的元素,而且可以类中的方法都是静态的;

(2)反射机制主要提供的作用:

    1:在运行时,提供判断任意对象所属的类;

    2:在运行时,构造任意类的对象; 

    3:在运行时,可以任意调用对象的方法

 

二、反射中常用的方法解析

   

   (1) 类的加载,有三种,分别是:

   --  forName(String className);

   --  类名.class

   --  对象名.getClass()  

   (2) 运行时,获取构造方法,从而生成对象

      Constructors  []constructor=类名.class.getConstructors():获取所有的公共的构造方法

      Constructor constructor=类名.class.getConstructor(parametersType) 返回具有指定参数类型的构造方法

      产生构造方法后,我们就可以利用我们这个构造方法实例化对象,与new对象的功能一样。可以使用构造方法construtor.newInstance(parameterType); 调用任意的构造方法,其中包括有参和无参的构造方法。

   (3)运行时,获取普通方法。

     Methods []methods=getDeclaredMethod()   返回 Method 对象的一个数组,这些对象反映此 Class 对象表示的类或接口声明的所有方法,包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法。

     还可以获取指定的方法,这里就不详述了,请参考java api

  (4)运行时,获取类的字段,方法跟获取普通方法的办法类似,只是在获取私有字段是要设置 setAccessialbe(true);

 

三、详细代码解析如下

 

package com.reflects;

import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class ReflectTest {

 
 public static void main(String[] args) throws Exception {

  //三种不同类型获取类字节码的方式
  String str="abc";
  Class clas1=str.getClass();
  Class clas2=String.class;
   // Class clas3=Class.forName("java.lang.class");
  
  //反射就是把java类中的各种成份映射到相应的java类中,
   //例如,一个类包括成员变量,方法,构造方法,包登信息,我们
  // 也可以使用一个个类来表示
  
  //反射---所有共有的构造方法,还可以获取指定的构造方法
    //通过指定参数类型获取,但是这里都是共有的,若是私有的则不行
  Constructor []constructor=String.class.getConstructors();
   for(Constructor c:constructor)
    System.out.println(c);
  
   //利用获取的构造方法new对象
  
   //编译的时候并不知道是哪个的构造方法只知道是一个构造方法
   //只有当运行的时候才知道是构造哪个实例对象
   //不执行,就不知道是哪个对象的构造方法
   Constructor cons=Class.forName("java.lang.String").getConstructor(String.class);//注意这里的写法
   String str1=(String)cons.newInstance("zhengjie");
   System.out.println("str1:"+str1);
  
   //new一个对象
   ReflectPoint rp1=new ReflectPoint(3,4);
   //获取对象对应的字段,这里的fY是类的字段,不是对象的字段
   //注意用下面的方式时,路径名要用完全限定名
  // Field fY=Class.forName("com.reflects.ReflectPoint").getField("y");
   try{
   
    //这里出错了这是可以是私有的
   Field fY=ReflectPoint.class.getDeclaredField("y");
    fY.setAccessible(true);
   //fied的值是多少呢
   System.out.println(fY.get(rp1));
  
   }catch(Exception e){
    System.out.println("我出错了");
   }
  
   System.out.println("*******************************");
  ReflectPoint rp=new ReflectPoint(3,4);
  change(rp);
  System.out.println(rp.toString());
  //获取成员方法,并调用成员方法
  Method method=String.class.getDeclaredMethod("charAt",int.class);
  //若第一个参数是null说明是静态方法
  System.out.println(method.invoke(str, 1));
  
  String a1=new String("nihao");
  int []a2=new int[]{1,2};
  printObject(a1);
  printObject(a2);
  
    }
 
   public static void change(Object obj) throws IllegalArgumentException, IllegalAccessException{
    //要求:扫描所有的对象的string对象
    Field []field=obj.getClass().getFields();
   for(Field f:field){
    if(f.getType()==String.class){
     String oldStr=(String)f.get(obj);
     String newStr=oldStr.replace('a', 'b');
     f.set(obj, newStr);
    
    }
   }
   }
    
   //数组反射
   public static void printObject(Object obj){
    Class clazz=obj.getClass();
    if(clazz.isArray()){
    int len= Array.getLength(obj);
    for(int i=0;i
     System.out.println(Array.get(obj, i));
    }
    }else{
     System.out.println(obj);
    }
   }
 

}


 class ReflectPoint{
     private int x;
     private  int y;
     public String str1="ball";
     public String str2="basketball";
     public String str3="itcast";
     
  public ReflectPoint(int x, int y) {
   super();
   this.x = x;
   this.y = y;
  }
  
  public String toString(){
   return "str1:"+str1+"   str2:"+str2+"  str3:"+str3; 
  }
 
    }

四、反射的简单应用:自定义框架

   主要代码如下:

     注:在java项目下,要建一个configure.properties配置文件

  public static void main(String []args){

 //这里容易出错,加载的时候,默认是工作目录下,我们一般要使用 getRealpath()获取路径名在拼接相应

 //的目录

  //配置文件都是用的    类加载器 加载
  InputStream is=ReflectPoint.class.getClassLoader().getResourceAsStream("configure.properties");

  //InputStream is=new FileInputStream(new File("configure.properties"));
  Properties props=new Properties();
  props.load(is);
  is.close();
  
  String className =props.getProperty("className");
  Collection collections=(Collection)Class.forName(className).newInstance();
  
  ReflectPoint1 rp1=new ReflectPoint1(1,1);
  ReflectPoint1 rp2=new ReflectPoint1(2,2);
  ReflectPoint1 rp3=new ReflectPoint1(3,3);
  
  collections.add(rp1);
  collections.add(rp2);
  collections.add(rp3);
  System.out.println("collections.size="+collections.size());

}

------- <a href="http://www.itheima.com" target="blank">android培训</a>、<a href="http://www.itheima.com" target="blank">java培训</a>、期待与您交流! ----------

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值