首页 > 其他 > 详细

黑马程序员-基础加强-反射

时间:2014-05-15 09:38:14      阅读:384      评论:0      收藏:0      [点我收藏+]

AVA反射机制是在运行状态中,对于任意一个,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。

反射的功能有:

  1. 在运行时检测对象的类型;
  2. 动态构造某个类的对象;
  3. 检测类的属性和方法;
  4. 任意调用对象的方法;
  5. 修改构造函数、方法、属性的可见性;

 

 示例1:获取对象的类型名称。

bubuko.com,布布扣
package heima;

public class ReflectionTest1{//获取对象的类型名称

    public static void main(String[] args){

        Foo f = new Foo();//创建一个Foo类实例对象

        System.out.println(f.getClass().getName());//通过   getClass方法获取对象的类名称     

    }

}

 

class Foo {//定义类Foo

    public void print() {

        System.out.println("abc");

    }

}
bubuko.com,布布扣

 

输出:

 bubuko.com,布布扣

示例2:调用未知对象的方法。

在下列代码中,设想对象的类型是未知的。通过反射,我们可以判断它是否包含print方法,并调用它。

bubuko.com,布布扣
package heima;

 

import java.lang.reflect.Method;

 

public class ReflectionTest2 {

    public static void main(String[] args){

        Foo2 f = new Foo2();//创建一个Foo类实例对象

         Method method;

        try {//注意这个方法会有异常,要抛出异常

            method = f.getClass().getMethod("print", new Class<?>[0]);//判断f的类有没有print方法,有就返回方法

            method.invoke(f);//调用放回的print方法

        } catch (Exception e) {

            e.printStackTrace();

        }          

    }

}

 

class Foo2 {

    public void print() {

        System.out.println("abc");

    }

}
bubuko.com,布布扣

 

 

输出:

 bubuko.com,布布扣

示例3:创建对象

bubuko.com,布布扣
package heima;

 

public class ReflectionTest3 {

 public static void main(String[] args) {

    Class<?> c = null;

     try{//抛出异常

         c=Class.forName("heima.Foo3");//获取类Foo3的字节码

     }catch(Exception e){

         e.printStackTrace();

     }

 

     // 创建Foo实例

     Foo3 f = null;

 

     try {//抛出异常

         f = (Foo3) c.newInstance();//创建字节码是c的类的实例对象

     } catch (Exception e) {

         e.printStackTrace();

     }  

 

     f.print();//调用Foo3中的print方法

 

}

}

class Foo3 {

    public void print() {

        System.out.println("abc");

    }

}
bubuko.com,布布扣

运行结果:

bubuko.com,布布扣

示例4:获取构造函数,并创建对象。

bubuko.com,布布扣
package heima;

 

import java.lang.reflect.Constructor;

 

public class ReflectionTest4 {

    public static void main(String[] args){

        // 创建Class实例

        Class<?> c = null;

        try{

            c=Class.forName("heima.Foo4");//获取类Foo4的字节码

        }catch(Exception e){

            e.printStackTrace();


        }

 

        // 创建Foo4实例

        Foo4 f1 = null;

        Foo4 f2 = null;

 

      

        Constructor<?> cons[] = c.getConstructors(); // 获取所有的构造函数,

 

        try {

            f1 = (Foo4) cons[0].newInstance();//用无参构造函数fl实例并赋值

            f2 = (Foo4) cons[1].newInstance("abc");//用参数是String的构造函数创建f2实例并赋值

        } catch (Exception e) {

            e.printStackTrace();

        }  

 

        f1.print();

        f2.print();

    }

}

 

class Foo4 {

    String s;

 

    public Foo4(){}

 

    public Foo4(String s){

        this.s=s;

    }

 

    public void print() {

        System.out.println(s);

    }

}
bubuko.com,布布扣

 

 

输出:

 bubuko.com,布布扣

此外,你可以通过Class实例来获取该类实现的接口、父类、声明的属性等。

 

示例5:通过反射来修改数组的大小。

bubuko.com,布布扣
package heima;

 

   import java.lang.reflect.Array;

    

   public class ReflectionTest5 {

       public static void main(String[] args) {

           int[] arr = { 1, 2, 3, 4, 5 };//创建数组

           int[] newArr = (int[]) changeArraySize(arr, 10);

           print(newArr);

           String[] atr2 = { "a", "b", "c", "d", "e" };

           String[] str1 = (String[]) changeArraySize(atr2, 10);

           print(str1);

       }

    

     

       public static Object changeArraySize(Object obj, int len) { // 修改数组的大小

           Class<?> arr = obj.getClass().getComponentType();//获取传入数组的类型,

           Object newArray = Array.newInstance(arr, len);//创建一个长度为len类型是arr的数组,用于保存改变后的数组

           int co = Array.getLength(obj);// 复制数组

           System.arraycopy(obj, 0, newArray, 0, co);

           return newArray;

       }

    

      

       public static void print(Object obj) {// 打印数组长度,并打印数组中的元素

           Class<?> c = obj.getClass();

           if (!c.isArray()) {//判断是否是数组类型

               return;

           }

    

           System.out.println(" 数组长度: " + Array.getLength(obj));

           for (int i = 0; i < Array.getLength(obj); i++) {//循环获取数组中的元素,注意这里的Array.toString方法起作用了,因为传入的参数是object类型,而不是arrag类型

               System.out.print(Array.get(obj, i) + " ");

           }

           System.out.println( );

 

       }

   }

 
bubuko.com,布布扣

输出:

 bubuko.com,布布扣

 

 Java 反射相关的API简介:
 位于java。lang。reflect包中
        Filed类:代表类的成员变量
        Constructor类:代表类的构造方法
        Class
     在 java 的Object类中的申明了数个应该在所有的java类中被改写的methods:hashCode(), equals(),clone(),toString(),getClass()等,其中的getClass()返回一个Class类型的对象。

     Class类十分的特殊,它和一般的类一样继承自Object,其实用以表达java程序运行时的 class和 interface,也用来表达 enum,array,primitive,Java Types 以及关键字void,当加载一个类,或者当加载器(class loader)的defineClass()被JVM调用,便产生一个Class对象, Class是Reflection起源,针对任何你想探勘的class(类),唯有现为他产生一个Class的对象,接下来才能经由后者唤起为数十多个的反射API。

     Java允许我们从多种途径为一个类class生成对应的Class对象。

Class。getSuperclass():Class类中的方法,返回该Class的父类的Class
  Class:类名.class
运行时调用Field内容
    变更Field不需要参数和自变量,首先调用Class的getField()并指定field名称,获得特定的Field对象后,便可以直接调用Field的 get(Object obj)和set(Object obj,Object value)方法

 

运行时生成instance
     想生成对象的实体,在反射动态机制中有两种方法,一个针对无变量的构造方法,一个针对带参数的构造方法,,如果想调用带参数的构造方法,就比较的麻烦,不能直接调用Class类中的newInstance(),而是调用Constructor类中newInstance()方法,首先准备一个Class[]作为Constructor的参数类型。然后调用该Class对象的getConstructor()方法获得一个专属的Constructor的对象,最后再准备一个Object[]作为Constructor对象昂的newInstance()方法的实参。
      在这里需要说明的是 只有两个类拥有newInstance()方法,分别是Class类和Constructor类Class类中的newInstance()方法是不带参数的,而Constructro类中的newInstance()方法是带参数的需要提供必要的参数。
    例:
      Class c=Class.forName("DynTest");
      Class[] ptype=new Class[]{double.class,int.class};
      Constructor ctor=c.getConstructor(ptypr);
      Object[] obj=new Object[]{new Double(3.1415),new Integer(123)};
      Object object=ctor.newInstance(obj);
      System.out.println(object);

 

黑马程序员-基础加强-反射,布布扣,bubuko.com

黑马程序员-基础加强-反射

原文:http://www.cnblogs.com/hansheng1988/p/3729059.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!