ClassLoader和Reflect

什么情况下使用ClassLoader来加载类?其实这个问题应该问,什么时候使用import来加载类,不能使用import的,就只能使用ClassLoader了。

使用import的条件:

1.必须是存在本地的,当程序员需要这个类的时候,内部类装载器会自动装载该类,对程序员来说是透明的。

2.编译的时候必须在现场,否则编译器会因为找不到引用文件而不能正常的编译。

 

ClassLoader分为3种,用一个简单的例子来说明:

    public static void printClassLoader(){
        ClassLoader loader = Thread.currentThread().getContextClassLoader();
        System.out.println("loader = " + loader.getClass());
        System.out.println("loader parent = " + loader.getParent().getClass());
        System.out.println("loader parent parent = " + loader.getParent().getParent());
    }

loader = class sun.misc.Launcher$AppClassLoader
loader parent = class sun.misc.Launcher$ExtClassLoader
loader parent parent = null

分别是: AppClassLoader,ExtClassLoader,BootClassLoader。从上面的代码可以看到继承关系。

 

Class反射则是对象描述类语义结构,在java.reflect包中,主要是3个反射类:Constructor,Method,Field。

我们有一个Car类

public class Car {
    private String name;

    public Car(){

    }

    public void showName(){
        System.out.println("name = " + name);
    }
}

里面比较坑的是,有name属性,但是没有提供修改的办法,我们可以用反射来修改。

  public static void getColor(){
        ClassLoader loader = Thread.currentThread().getContextClassLoader();
        try{
            Class clazz = loader.loadClass("Car");
            Object car = (Object)clazz.newInstance();

            Field name = clazz.getDeclaredField("name");
            name.setAccessible(true);
            name.set(car,"carry");//在这里修改属性

            Method method = clazz.getMethod("showName");
            method.invoke(car,(Object[])null);

        }catch(Exception e){
            System.out.println(e.toString());
        }
    }

这是平时写代码的时候,比较有用的技巧。

posted @ 2016-05-19 15:23  身带吴钩  阅读(276)  评论(0编辑  收藏  举报