类装载器ClassLoader
类装载器就是寻找类的字节码文件,并构造出类在JVM内部表示的对象组件。
类装载器把一个类装入JVM中,要经过三步:
1.装载:查找和导入Class文件;
2.链接:执行校验、准备和解析(解析是可以选择的);
3.初始化:对类的静态变量、静态代码块执行初始化工作;
类装载工作由ClassLoader及其子类负责。JVM在运行时会产生三个ClassLoader:根装载器、ExtClassLoader(扩展类装载器)和AppClassLoader(系统类装载器)。
根装载器不是ClassLoader的子类,它使用C++编写,因此,我们在JAVA中看不到它,根装载器负责装载JRE的核心类库,如JRE目标下的rt.jar、charsets.jar等。
ExtClassLoader和AppClassLoader都是ClassLoader的子类。其中,ExtClassLoader负责装载JRE扩展目录ext中的类包,AppClassLoader负责装载Classpath路径下的类包。
这三个类装载器之间存在父子层级关系,即根装载器是ExtClassLoader的父装载器,ExtClassLoader是AppClassLoader的父装载器。
publicclass ClassLoaderTest { publicstaticvoid main(String[] args) { ClassLoader loader = Thread.currentThread().getContextClassLoader(); System.out.println("current loader---"+loader); System.out.println("parent loader---"+loader.getParent()); System.out.println("grandparent loader---"+loader.getParent().getParent()); } } |
上面代码运行结果:
current loader---sun.misc.Launcher$AppClassLoader@20cf2c80 parent loader---sun.misc.Launcher$ExtClassLoader@1729854 grandparent loader---null |
由于根加载器在java中访问不到,所以返回null。
每一个类在JVM中都拥有一个对应的java.lang.Class对象,它提供了类结构信息的描述。Class对象是在装载类时由JVM通过调用类装载器中的defineClass()方法自动构造的。
Java反射机制
Class反射对象描述类语义结构,可以从Class对象中获取构造函数、成员变量、方法等类元素的反射对象,并以编程的方式通过这些反射对象对目标类对象进行操作。这些反射对象类在java.lang.reflect包中。主要的反射类有Constructor、Method、Field、ClassLoader等。
publicclass PrivateCar { private String color; protectedvoid drive(){ System.out.println("Drive private car! The color is :"+color); } }
publicclass PrivateCarReflect { publicstaticvoid main(String[] args) throws Throwable { //通过类装载器获得PrivateCar类对象 ClassLoader loader = Thread.currentThread().getContextClassLoader(); Class clazz = loader.loadClass("com.quietboy.reflect.PrivateCar"); //得到实例 PrivateCar pcar = (PrivateCar)clazz.newInstance(); //访问属性,并设置属性 Field color = clazz.getDeclaredField("color"); color.setAccessible(true);//取消Java语言访问检查,以访问private变量 color.set(pcar, "红色"); //访问方法,并调用方法 Method drive = clazz.getDeclaredMethod("drive", null); drive.setAccessible(true);//取消Java语言访问检查,以访问protected方法 drive.invoke(pcar, null);
} } |
只要JVM的安全机制允许,反射机制可以绕过限制,访问私有变量、调用私有方法。
本文出自 “quietboy's blog” 博客,请务必保留此出处http://quietboy.blog.51cto.com/6711298/1429347