黑马程序员:论反射的正确使用以及应用范围2·个人感悟 反射有啥用?

来源:互联网 发布:c语言中删除文件 编辑:程序博客网 时间:2024/05/22 00:23

android培训、java培训、期待与您交流!


JAVA反射机制:

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
JAVA反射(放射)机制:“程序运行时,允许改变程序结构或变量类型,这种语言称为动态语言”。从这个观点看,Perl,Python,Ruby是动态语言,C++,Java,C#不是动态语言。但是JAVA有着一个非常突出的动态相关机制:Reflection,用在Java身上指的是我们可以于运行时加载、探知、使用编译期间完全未知的classes。换句话说,Java程序可以加载一个运行时才得知名称的class,获悉其完整构造(但不包括methods定义),并生成其对象实体、或对其fields设值、或唤起其methods。(from 百度百科)


就像指针是c++的灵魂一样,“反射”也是java的精髓。我们都知道反射是重要的、伟大的,但是很多情况下(我们初学者)是完全不理解反射究竟能做什么的。


一方面,是因为,我们所接触的程序实在太简单,简单的完全不用到反射(比如气泡排序或者快速排序);另一方面,很多时候,我们在框架里所用到的反射,都是别人封装好的。我们不必理解其原理,只要拿过来用就可以了。


所以,假设我们既不去写框架,又写比较简单的程序,我们学习反射还有什么用呢?


我想是没用的,所以我对反射并没有太过关注。直到我遇到一个现实的问题(注·即上一篇中所遇到的问题)又查询相关知识,然后通过反射调用,大大减少了代码量的书写,而且使得程序更为简洁易懂。后来我又接触了spring mvc的底层(虽然只是很小很小的一部分),再次对反射有了深刻的理解。通过注解和反射调用,在web项目中可以简化相当程度的代码量。程序员只要专注于底层DAO以及UI界面的开发,之间的串联交给spring去搞定就可以了。


在一般的入门性质的开发中,我还是用不到反射。因为无论是dao层还是action还是飞来飞去的post,和反射都没什么关系。还是那句话,我只要拿来用,并不关心其原理。


我一直知道,反射可以这么用:

1.获得一个类

Class c = 对象名.getClass();
Class c = Class.forName(String name);

然后根据模版来获取其对应的类对象: c.newInstance();


获取类的属性:

Filed类----c.getFiled(String pname)  获得指定属性(公共字段)

Filed类----c.getDeclearedFiled(String pname)  获得指定属性(所有权限字段)

Filed[]----c.getFileds(String pname)  获得所有属性(公共字段)

Filed[]----c.getDeclearedFileds(String pname)  获得所有属性(所有权限字段)

获取类的方法:

Method类----c.getMethod(String methodName,class[] params)  获得指定方法(公共方法)

Method类----c.getDeclearedMethod(String methodName,class[] params)  获得指定方法(所有方法)

Method[]----c.getMethods(String methodName,class[] params)  获得所有方法(公共方法)

Method[]----c.getDeclearedMethods(String methodName,class[] params)  获得所有方法(所有权限方法)

当然,还有注解@interface,spring就是通过各种注解来进行注入串联。可是在一般的编程中,基本用不到。所谓的高耦合低聚合,在OOP中,也可以用继承等特性来加以修饰。换句话说,我们现在所编的程序,简单到根本用不到注解。我们将来如果不去写框架,那么更是用不到注解。


还有那个经典的java面试题:如何在一个泛型为Integer里的Arraylist中存入一个String类型的值。是啊,我是知道,完全可以这么写。

package refi;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;import java.util.ArrayList;import java.util.List;public class Test {    /**     * @param args     */    public static void main(String[] args) {        List<Integer> arrayList=new ArrayList<Integer> ();        Method[] m=arrayList.getClass().getMethods();//获得方法        for(int i=0;i<m.length;i++){                if(m[i].getName().indexOf("add")!=-1){//判断方法                Class<?>[] c=m[i].getParameterTypes();//判断参数                if(c.length<2){                    try {                        m[i].invoke(arrayList, "stupid");                    } catch (IllegalAccessException e) {                        // TODO Auto-generated catch block                        e.printStackTrace();                    } catch (IllegalArgumentException e) {                        // TODO Auto-generated catch block                        e.printStackTrace();                    } catch (InvocationTargetException e) {                        // TODO Auto-generated catch block                        e.printStackTrace();                    }                    break;                }            }        }        for(int i=0;i<arrayList.size();i++){            System.out.println("==>"+arrayList.get(i));        }    }}

可是在处理实际问题的时候,我并不会想到要这么做。如果真的要将一个String类型放到list里,我想我会把list定义成<String>泛型然后直接放进去的。


所以现阶段,我们学习的时候,只要对反射有个一般了解就可以。多了,用不到。等将来有一天我们略有心得,等有一天我们已经掌握了二十三种设计模式,有了几十万行的代码书写,有了对代码结构化以及功能化的意识了以后。我们才i可能会意识到,原来反射和和注解是那么有用的。


至于现在嘛,我只要知道java有这个功能就可以了。




0 0