今天淘宝实习生2面,效果不太好,对应用比较熟,对底层的东西掌握比较薄弱。
问了一下classLoader的东西都不太清楚,发现自己还菜的很,面试官比较好说话,最后给我两个建议:1,多去看看底层的东西。用的东西很简单,只要学一学谁都会,只有掌握底层的东西才能有自己的知识体系,才能有更大的发展空间;2,面试的时候,不知道的问题就说不知道,一定不要猜!
下午看陈雄华的《精通Spring2.X--企业应用开发详解》的时候看到了ClassLoader的东西,研读以后写写心得。
ClassLoader也就是类装载器,把一个类装入JVM中要经过以下步骤:
1、装载:查找和导入Class文件。
2、链接:执行校验,准备和解析步骤。
a)校验:检查载入class文件数据的正确性。
b)准备:给类的静态变量分配存储空间。
c)解析:将符号引用转成直接引用。
3、初始化:对类的静态变量,静态代码块执行初始化工作。
ClassLoader是一个重要的JAVA运行时组件,它负责在运行时查找和装入Class字节码文件。JVM在运行时会产生三个ClassLoader,分别是根装载器,ExtClassLoader(扩展类装载器),AppClassLoader(系统类装载器)。其中根装载器不是ClassLoader的子类,是用C++编写的,负责加载JRE的核心类库。ExtClassLoader,AppClassLoader都是ClassLoader的子类。ExtClassLoader负责装载JRE扩展目录ext中的JAR类包;AppClassLoader负责装载ClassPath路径下的类包。
JVM装载类是使用“全盘负责委托机制”,“全盘负责”就是当一个ClassLoader装载一个类时,除非显式调用另外一个ClassLoader,该类所依赖及引用的类也由这个ClassLoader载入;“委托机制”是指先委托父类装载器寻找目标类,只有在找不到的情况下才从自己的类路径中查找并装载目标类。
ClassLoader中包含常用方法:
·Class loadClass(String name)
name指定类装载器需要装载类的名字(必须使用全限定名)。
·Class loadClass(String name,boolean resolve)
resolve参数告诉类装载器是否需要解析该类。
·Class definaClass(String name,byte[] b,int off, int len)
name为全限定名,该类文件的字节数组转化成JVM内部的java.lang.Class对象,字节数组可以从本地文件系统,远程网络获取。
·Class findSystemClass(String name)
从本地文件系统载入Class文件,如果本地文件不存在该Class文件,将抛出ClassNotFoundException异常,该方法是JVM默认使用的装在机制。
·Class findLoaderClass(String name)
调用该方法来查看ClassLoader是否已装入某个类。如果已装入,那么返回java.lang.Class对象,否则返回null。如果强行装载已存在的类,将会抛出链接错误。
类文件被装载并解析后,在JVM将拥有一个对应的java.lang.Class类描述对象,该类的实例都拥有指向这个类描述对象的引用,而类描述对象又拥有指向关联ClassLoader的引用。
代码示例:
ClassLoader loader = Thread.currentThread().getContextClassLoader();//得到类加载器
Class clazz = loader.loadClass("com.waiting.reflect.Car");//得到Car类描述对象
Constructor cons = clazz.getDeclaredConstructor((Class[])null);//获取Car类的构造器
Car car = (Car)cons.newInstance();//得到实例化的car对象