Java的反射机制

Java的反射机制

Java反射机制就是Java语言被视为准动态语言的关键性质。Java反射机制的核心就是允许在运行时通过Java Reflection APIs来取得已知名字的class类的相关信息,动态地生成此类,并调用其方法或修改其域(甚至是本身声明为private的域或方法)。Class类是整个Java反射机制的源头。一切关于Java反射的故事,都从Class类开始。使用Java反射,我们首先得到Class类的对象,在得到一个类的Class类对象之后,就可以开始使用Java反射机制。

Java的类反射所需要的类分别为:FieldConstructionMethodClassObject。这五个类的作用分别为:

1Field类:提供有关类或接口的属性的信息,以及对它的动态访问权限。反射的字段可能是一个类(静态)属性或实例属性,简单的理解可以把它看成一个封装反射类的属性的类
2Constructor类:提供关于类的单个构造方法的信息以及对它的访问权限。这个类和Field类不同,Field类封装了反射类的属性,而Constructor类则封装了反射类的构造方法
3Method类:提供关于类或接口上单独某个方法的信息。所反映的方法可能是类方法或实例方法(包括抽象方法)。 这个类不难理解,它是用来封装反射类方法的一个类。
4Class类:类的实例表示正在运行的 Java 应用程序中的类和接口。枚举是一种类,注释是一种接口。每个数组属于被映射为 Class 对象的一个类,所有具有相同元素类型和维数的数组都共享该 Class 对象
5Object类:每个类都使用 Object 作为超类。所有对象(包括数组)都实现这个类的方法

代码+注释:

下面我写一个比较完整的小例子,来说明Java的反射类能做些什么

    import java.lang.reflect.Constructor;  

    import java.lang.reflect.Method;  

      

    public class LoadMethod {  

    public Object Load(String cName,String MethodName,String[] type,String[] param){  

    Object retobj = null;  

    try {  

    //加载指定的Java  

    Class cls = Class.forName(cName);  

      

    //获取指定对象的实例  

    Constructor ct = cls.getConstructor(null);  

    Object obj = ct.newInstance(null);  

      

    //构建方法参数的数据类型  

    Class partypes[] = this.getMethodClass(type);  

      

    //在指定类中获取指定的方法  

    Method meth = cls.getMethod(MethodName, partypes);  

      

    //构建方法的参数值  

    Object arglist[] = this.getMethodObject(type,param);  

      

    //调用指定的方法并获取返回值为Object类型  

    retobj= meth.invoke(obj, arglist);  

      

    }  

    catch (Throwable e) {  

    System.err.println(e);  

    }  

    return retobj;  

    }  

      

    //获取参数类型Class[]的方法  

    public Class[] getMethodClass(String[] type){  

    Class[] cs = new Class[type.length];  

    for (int i = 0; i < cs.length; i++) {  

    if(!type[i].trim().equals("")||type[i]!=null){  

    if(type[i].equals("int")||type[i].equals("Integer")){  

    cs[i]=Integer.TYPE;  

    }else if(type[i].equals("float")||type[i].equals("Float")){  

    cs[i]=Float.TYPE;  

    }else if(type[i].equals("double")||type[i].equals("Double")){  

    cs[i]=Double.TYPE;  

    }else if(type[i].equals("boolean")||type[i].equals("Boolean")){  

    cs[i]=Boolean.TYPE;  

    }else{  

    cs[i]=String.class;  

    }  

    }  

    }  

    return cs;  

    }  

      

    //获取参数Object[]的方法  

    public Object[] getMethodObject(String[] type,String[] param){  

    Object[] obj = new Object[param.length];  

    for (int i = 0; i < obj.length; i++) {  

    if(!param[i].trim().equals("")||param[i]!=null){  

    if(type[i].equals("int")||type[i].equals("Integer")){  

    obj[i]= new Integer(param[i]);  

    }else if(type[i].equals("float")||type[i].equals("Float")){  

    obj[i]= new Float(param[i]);  

    }else if(type[i].equals("double")||type[i].equals("Double")){  

    obj[i]= new Double(param[i]);  

    }else if(type[i].equals("boolean")||type[i].equals("Boolean")){  

    obj[i]=new Boolean(param[i]);  

    }else{  

    obj[i] = param[i];  

    }  

    }  

    }  

    return obj;  

    }  

    }  

Java反射机制的作用:

适用于创建以非常普通的方式与对象协作的库。增加程序的灵活性,避免将程序写死到代码里,典型应用是Spring。例如: 实例化一个 person()对象, 不使用反射, new person(); 如果想变成 实例化 其他类, 那么必须修改源代码,并重新编译。

但反射有两个缺点。第一个是性能问题。用于字段和方法接入时反射要远慢于直接代码。性能问题的程度取决于程序中是如何使用反射的。如果它作为程序运行中相对很少涉及的部分,缓慢的性能将不会是一个问题。即使测试中最坏情况下的计时图显示的反射操作只耗用几微秒。仅反射在性能关键的应用的核心逻辑中使用时性能问题才变得至关重要。

 

posted on 2017-06-16 14:11  大脸猫~蜜  阅读(111)  评论(0)    收藏  举报