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()); } }
这是平时写代码的时候,比较有用的技巧。