ClassLoader和Reflect

什麼狀況下使用ClassLoader來加載類?其實這個問題應該問,何時使用import來加載類,不能使用import的,就只能使用ClassLoader了。java

使用import的條件:程序員

1.必須是存在本地的,當程序員須要這個類的時候,內部類裝載器會自動裝載該類,對程序員來講是透明的。spa

2.編譯的時候必須在現場,不然編譯器會由於找不到引用文件而不能正常的編譯。code

 

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 = nullblog

分別是: AppClassLoader,ExtClassLoader,BootClassLoader。從上面的代碼能夠看到繼承關係。繼承

 

Class反射則是對象描述類語義結構,在java.reflect包中,主要是3個反射類:Constructor,Method,Field。get

咱們有一個Car類編譯器

public class Car {
    private String name;

    public Car(){

    }

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

裏面比較坑的是,有name屬性,可是沒有提供修改的辦法,咱們能夠用反射來修改。io

  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());
        }
    }

這是平時寫代碼的時候,比較有用的技巧。

相關文章
相關標籤/搜索