黑马程序员--java高新技术之反射

---------------------- ASP.Net+Unity开发.Net培训、期待与您交流! ----------------------

  java反射学习总结:
  1.为什么要用反射:普通的java编程,只能在编译期执行面向类型的操作,运行时类型信息使得你可以在程序运行时发现和使用类型信息,运用反射,我们可以在程序运行时
  获得和使用类型信息。
  2.反射的基石Class类:java中的类是用来描述对象的,而用来描述对象的这些类本身也是对象,用来描述他们的类就是Class类,Class类描述了java中所有类对象的属性
  字段,方法,构造函数,父类,实现的接口等等
  3.获得类的Class对象的方式:1.可以通过类名.Class来获取 2.可以通过类的对象的getclass()方法来获取 3.可以通过Class类的静态方法forname()来获取
     1.通过类名.Class:
        Class class=String.class//未导包需要全域名,即:java.lang.String

     2.通过实例对象的getClass()方法:
        Class class="test".getClass();   

     3.通过Class类的forName()方法:

        Class class=Class.forName("java.lang.String")//这里需要全域名.       


  4.通过Class对象获取一个类的构造方法

  1.可以通过Class对象的getConstructor(parameterTypes)方法来获得具有给定参数列表的构造函数。
  2.可以通过Class对象的getConstructors()获得该对象所有的构造方法。

  3.对于构造方法私有的,可以通过getDeclaredConstructor(parameter Types)函数来获取

   比如:
     获取String类的所有的构造方法:

      Constructor[] constructor=String.class.getConstructors();
     获取String类的String参数的构造方法:

      Constructor constructor=String.class.getConstructor(String.class):

     通过String类的实例对象获取构造方法:

      Constructor[] costructor="String".getclass.getConstructors();
     获取String类的私有的构造方法: 

      Constructor constructor=String.class.getDeclaredConstructor(parameter Types);
     获取String类所有的私有构造方法:

      Constructor[] constructor=String.class.getDeclaredConstructors():


  5.如果获得的Class对象的属性是私有的,那么我们是不能直接进行访问的,要想访问私有的属性,可以通过setAccessable(true)来去除访问限制

 
     /**
      *getDeclaredConstructors可以得到一个类所有的构造方法,当然对于私有的
      *构造方法,还要去除权限修饰符后才能访问,这通过setAccessable(true)来
      *实现,这样,我们就可以通过反射构造出那些用常规方法无法构造的对象来
      *比如,单例设计中的类,我们无法new出他的实例对象,但我们可以通过反射
      *创建他的实例对象。
      */

     constructor[] constructors=String.class.getDeclaredConstructors();//获得所有的构造方法
     for(constructor constructor:constructors){
     constructor.setAccessable(true);//去除权限修饰符,这样无论这个构造方法是什么访问权限我们都能访问
     constructor.newInstance();//通过默认构造方法创建出实例对象
     }


  6.通过反射调用Class对象中的方法:
    1.通过反射的方式创建一个字符串,并调用其中的substring()方法:

  Class obj=String.class;//获得String类的Class对象
  Constructor cons=obj.getConstructor(String.class);//取得String类中参数为String的构造函数
  String str=cons.newInstance("我是通过反射创建的字符串");//通过反射到的构造函数创建实例对象
  Method method=obj.getMethod("substring",int.class);//通过反射获得String类中的substring方法
  method.invoke(obj,2);//通过反射调用obj对象身上的substring方法
  
 


 6.通过反射调用对象的使用方法:

      /**
       *通过反射调用私有方法首先要知道被调用的私有方法的签名,
       *即方法名称和参数类型,然后通过getDeclaredMethod()方法
       *取得这个方法,然后通过setAccessable(true)来去除方法上
       * 的权限修饰符,然后通过invoke()方法调用该私有方法,调用
       *时要传递正确的参数,否则会调用失败
       *
       */
       Class Test{//用来测试的类,其中有一个私有方法
        private show(String msg){
          System.out.println("当前传递的消息是:"+msg);        
        }
       }
      Test t=Test.class.newInstance():
      Method method=Test.class.getDeclaredMethod("show",String.class);
      method.setAccessable(true);
      method.invoke(t,"我正在通过反射调用私有方法");



  7.字段的反射,字段的反射和方法的反射类似:
    1.1通过反射访问Class对象实例中的公有字段,以test类为例:

      Field field=Test.class.getField("x");
      System.out.println(field.get(new Test());

     1.2.通过反射设置Class对象实例中的公有字段,以test类为例:

       Test t=new Test():
       Field field=test.class.getField("x");//通过反射取得Test类上的公有字段x
       field.set(t,300); //通过反射设置对象t上x字段的值

    2.通过反射访问和设置Class对象实例中的私有字段,以test类为例:
      Test t=new Test():
      Field field=test.class.getDeclaredField("Str");//获得私有字段
      field.setAccessable(true);//去除权限修饰符
      System.out.println(field.get(t); //访问test类中的私有字段
      field.set(t,"hello");   //设置test类中的私有字段

  8.九个预定义的Class实例对象:
   int.class==Integer.TYPE;
   boolean.class==Boolean.TYPE;
   char.class== Character.TYPE;
   long.class==Long.TYPE;
   float.class==Float.TYPE;
   double.class==Double.TYPE;
   short.class==Short.TYPE;
   byte.class==Byte.TYPE;
   void.class==Void.TYPE;


  9.通过反射对参数是数组的方法的调用:

    /**
      *因为java会对数组参数进行自动拆包,因此对参数是数组的方法如果以常规的反射去调用,
      *会出现java.lang.IllegalArgumentException: wrong number of arguments异常。这时
      *应该将数组参数转型为Object,典型的应用是调用一个类中的main()方法
      */
    Method method=ReflectDemo.class.getMethod("main",String[].class);
    method.invoke(null,(Object)new String[]{});



  10.数组的反射:
     1.具有相同维数和数据类型的数组属于同一个类型,即具有相同的Class对象。
     2.代表数组的Class实例对象的getSuperClass()方法返回的父类为Object类对应的Class
     3.基本类型的一维数组可以当成Object类型使用,但不能当成Object[]使用,非基本类型的一维数组,既可以当成Object类型使用,又可以当成Object[]使用
     4.数组反射要用java.lang.reflect.array类:

     

     /**
       *数组对象的反射和一般对象的反射有点不同,因为数组主要
       *是用来保存数据的,我们很少用到数组对象中的方法,也很少
       *通过反射数组对象的构造方法来创建一个新数组,我们关心的
       *只是它里面的数据,这就用到了另外一个操作数组的类:Array类
       *通过它,我们可以从数组中根据下标取出数据,无论这是什么样
       *数组,只要他是数组,都可以通过这个类取出其中数据      
       */
 
        public void printObject(Object obj){
         Class class=obj.getClass();
         if(class.isArray()){//判断当前对象是否为数组对象
           int len=Array.getLenth(obj);
           for(int i=0;i<len;i++){
           System.out.println(Array.get(obj,i));//通过Array类取出数组对象中的数据,并在控制台打印
           }
        }else{
          System.out.println(obj);//不是数组对象直接打印
        } 
        }



  11.通过反射实现框架:
    框架与框架要实现的核心功能:一般框架要调用用户的类,而框架完成的时候用户可能还没有创建自己的类,框架要调用用户的类,就不能用常规的new来调用了,可以通过反射
    的方式,用配置文件的方式加载,这就是框架要实现的核心功能。


---------------------- ASP.Net+Unity开发.Net培训、期待与您交流! ----------------------

详细请查看:www.itheima.com 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值