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

来源:互联网 发布:zblog php自适应模板 编辑:程序博客网 时间:2024/06/06 03:26
---------------------- 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
原创粉丝点击