java反射机制的学习心得

概述

以前在了解Spring的类加载机制的时候,了解了java的反射机制。可是,我对反射理解一直不深。也一直有点疑惑:Spring为何利用反射建立对象?直接new对象和依靠反射建立对象有什么区别?什么是动态加载类?java

什么是反射?

要想知道反射究竟是什么,首先须要知道java的类加载和对象建立的机制。.net

当咱们写完一个java文件的时候,后缀是.java。在咱们利用IDE执行java文件的时候,其实IDE也帮咱们运行了javac,即java编译器。编译器会将.java文件编译成.class文件。java虚拟机会去读取.class文件。这时候,类加载器ClassLoader会将这些类,以及该java文件import的类加载到JVM中的方法区。这些被加载的类的类型都是Class,习惯称之为类对象code

对象的建立,便是根据这些Class类对象,在堆区建立对象。对象

这时候,反射就很好理解了。反射的目的就是获取这些Class类对象blog

反射的方式

目前我知道能够利用反射返回类对象的方式有四种:继承

1.若是你知道类的路径:接口

Class aclass = Class.forName("类的路径"); //如java.util.ArrayList,你就能够得到ArrayList的类对象

2.若是你知道类:get

Class aclass = ArrayList.class;

3.若是你实例化对象:编译器

ArrayList<Integer> array = new ArrayList<Integer>();
Class aclass = array.getClass();

4.经过类加载器加载(我的不常常用忘记了hhh)博客

类对象Class的用法

  1. 得到Class类对象,咱们能够很是轻松的获取到该类的字段和方法,咱们甚至能够获得该类的父类:如:getMethod,getConstructor... 就是获取类对象的方法,构造器等等,这些能够去网上查到相应的资料,这里不作赘述。

  2. 咱们获得了Class类对象,咱们就能够利用Class类对象建立一个对象实例了!这里就是工厂模式的利用方法,将全部类建立的工做交给工厂类实现,并将建立的对象返回便可。这样就能方便管理对象建立的工做。利用反射,建立对象的例子:

//利用反射机制建立一个ArrayList的对象
Class aclass = Class.forName("java.util.ArrayList"); //依靠反射,获取ArrayList的类对象
ArrayList<Integer> array = (ArrayList<Integer>)aclass.newInstance(); //利用Class类对象,建立ArrayList类

什么是动态加载?

以前我也不知道什么是静态加载,什么是动态加载,看了一我的的博客豁然开朗:博客链接

他说的很清楚了:java中的new方法是静态加载,由于new方法是在编译阶段就会检查,而不是在运行阶段。反射是能够在运行时建立对象,调用对象的方法、变量等。

该博客做者利用了两个例子进行诠释

静态加载:

//定义接口
interface OfficeAble{
    public void start();
}
//Main
class Office{
    public static void main(String[] args){
        if(args[0].equals("Word")){
            Word w = new Word();
            w.start();
        }
        if(args[0].equals("Excel")){
            Excel e = new Excel();
            e.start();
        }
    }
//Word类
class Word implements officeAble{
    public void start(){
        System.out.println("Word Start");
    }

这样会报错。静态加载会在编译阶段将Class类对象加载进方法区,由于这里没有定义Excel类,编译器就会报错。

动态加载:

//接口和Word类同上,修改一下Main方法
class Office{
    public static void main(String[] args){
        try{
            Class c = Class.forName(args[0]);
            OfficeAble oa = (OfficeAble)c.newInstance();
            oa.start();
        }
        catch(Exception e){
            e.printStackTrace();
        }
        
    }

这样就能成功运行,利用反射,只要知道接口,能很好的提升扩展性!无论写多少个类,只要继承接口,均可调用。

相关文章
相关标签/搜索