反射的介绍以及动态加载类——反射_1

无简介

1.首先理解什么是反射?

反射(Reflection)能够让运行于JVM中的程序检测和修改运行时的行为。

2.为什么需要反射?

反射能够让我们:

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

3.Class类实例对象的方法

Class实例对象的三种方法:

a.通过类的隐含的静态成员class;  b.通过该类的getClass()方法; c.通过类的全称,用Class.forName(“类名”)获取。

以上三种方法可以参考下面的代码:

class ClassDemo0{ 
    public static void main(String[] args) { 
        Foo foo1=new Foo(); 
        //a,任何一个类都有一个隐含的静态成员class 
        Class c1=Foo.class; 
        //b,已知该类,通过getClass方法 
        Class c2=foo1.getClass(); 
   
        //注c1,c2表示Foo类的类类型(class type) 
        System.out.println(c1==c2);  //true, 一个类只可能是Class类的一个实例对象 
   
        //c,通过类的全称获取 
        Class c3=null; 
        try{ 
            c3=Class.forName(“Foo”); 
        }catch(ClassNotFoundException e){ 
            e.printStackTrace(); 
        } 
        System.out.println(c2==c3);//true 
   
        //通过类的类类型创建该类的对象实例,通过c1,c2,c3创建Foo的对象实例 
        try{ 
            Foo foo=(Foo)c1.newInstance();//前提:该类要有无参构造函数 
        }catch(InstantiationException e){ 
            e.printStackTrace(); 
        }catch(IllegalAccessException e){ 
            e.printStackTrace(); 
        } 
    } 

   
class Foo{ 
    void print(){ 
        System.out.println(“Foo”); 
    } 
}

4.动态加载类

首先我们要了解:为什么要动态加载? 当我们编写一个程序的时候,我们首先要编写代码,然后进行编译,编译通过之后才可以运行。 然后我们要清楚,当我们使用new的方式来创建一个对象的时候[ new Book() ],Book这个类就要被静态加载。

(编译时刻加载的类是静态加载类,运行时刻加载的类是动态加载类)

现在,我们假设有这么一段代码:

class Office{ 
    public static void main(String[] args) { 
   
         //new创建对象 是静态加载类,在编译时刻就需要加载所有的可能使用到的类,(若没有建Word类),编译不通过 
        //若有建Word类,但Excel类没建,但编译还是不能通过 
        //希望用到时再加载,可以通过动态加载类实现 
        if(“Word”.equals(args[0])){ 
            Word w=new Word();     
            w.start(); 
        } 
   
        if(“Excel”.equals(args[0])){ 
            Excel e=new Excel(); 
            e.start(); 
        } 
    } 
}

再假设Word这个类是存在的,那么new Word()这句话编译是可以通过的。 但是如果Excel这个类不存在,那么编译就会报错,编译不通过,程序就不能运行。 也就是,因为一个类的错误,影响了整体程序的运行。 那么我们要避免这样的情况,应该怎么做呢? 在这种情况之下,就可以使用动态代理。

class OfficeBetter{ 
    public static void main(String[] args) { 
        try{ 
            //动态加载类,在运行时加载 
            Class c=Class.forName(args[0]); 
            //通过类类型,创建该类对象 
            //Word w=(Word)c.newInstance();    //如果加载的是Excel呢? 
            //Excel e=(Excel)c.newInstance();  //如果加载的是Excel呢? 
   
            //后期增加功能就不用改动OfficeBetter,实现在线升级,扩展性更强 
            OfficeAble oa=(OfficeAble)c.newInstance();  //所以做一个标准————功能型的类尽量使用动态加载 
            oa.start(); 
        }catch(Exception e){ 
            e.printStackTrace(); 
        } 
    } 

   
interface OfficeAble{ 
    public void start(); 

   
class Word implements OfficeAble{ 
    public void start(){ 
        System.out.println(“word…start…”); 
    } 

   
class Excel implements OfficeAble{ 
    public void start(){ 
        System.out.println(“Excel…start…”); 
    } 
}

可以看到,正常情况下,如果需要在officeBetter这个类中通过new的方式将我们可能用到的所有的类都实例化出来。 这样不仅占用了内存,同时也存在如果一个出现错误其他的也不能运行这样的问题。       而我们现在通过一个借口,让子类去继承,然后我们通过获得传递过来的class,创建出该类的对象,这个对象就是子类的对象了。 在这种情况下,如果有新增或者减少功能(比如在旧的方法的情况下要添加一个pencil),就不需要对这个类进行修改,只需要新建新的类就可以了。   慕课网反射动态加载讲解视频原址 [embed]http://v1.mukewang.com/f7597ee8-1a64-4b6d-8682-9e8469be63a8/H.mp4[/embed]

-------------本文结束  感谢您的阅读-------------
下次一定