您的位置:首页 > 编程语言 > Java开发

Java基础知识――类装载器与反射机制

2014-06-21 17:53 459 查看

类装载器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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: