java面试题28 牛客 下面有关java classloader说法错误的是?
java面试题28 牛客 下面有关java classloader说法错误的是?
A Java默认提供的三个ClassLoader是BootStrap ClassLoader,Extension ClassLoader,App ClassLoader
B ClassLoader使用的是双亲委托模型来搜索类的
C JVM在判定两个class是否相同时,只用判断类名相同即可,和类加载器无关
D ClassLoader就是用来动态加载class文件到内存当中用的
蒙蔽树下蒙蔽果,蒙蔽树上你和我
Java语言系统自带有三个类加载器:
Bootstrap ClassLoader 最顶层的加载类,主要加载核心类库,%JRE_HOME%\lib下的rt.jar、resources.jar、charsets.jar和class等。另外需要注意的是可以通过启动jvm时指定-Xbootclasspath和路径来改变Bootstrap ClassLoader的加载目录。比如java -Xbootclasspath/a:path被指定的文件追加到默认的bootstrap路径中。我们可以打开我的电脑,在上面的目录下查看,看看这些jar包是不是存在于这个目录。
Extention ClassLoader 扩展的类加载器,加载目录%JRE_HOME%\lib\ext目录下的jar包和class文件。还可以加载-D java.ext.dirs选项指定的目录。
Appclass Loader也称为SystemAppClass 加载当前应用的classpath的所有类。
我们上面简单介绍了3个ClassLoader。说明了它们加载的路径。并且还提到了-Xbootclasspath和-D java.ext.dirs这两个虚拟机参数选项。
加载顺序?
我们看到了系统的3个类加载器,但我们可能不知道具体哪个先行呢?
我可以先告诉你答案
Bootstrap CLassloder
Extention ClassLoader
AppClassLoader
为了更好的理解,我们可以查看源码。
看sun.misc.Launcher,它是一个java虚拟机的入口应用。
public class Launcher {private static Launcher launcher = new Launcher();private static String bootClassPath =System.getProperty("sun.boot.class.path");public static Launcher getLauncher() {return launcher;}private ClassLoader loader;public Launcher() {// Create the extension class loaderClassLoader extcl;try {extcl = ExtClassLoader.getExtClassLoader();} catch (IOException e) {throw new InternalError("Could not create extension class loader", e);}// Now create the class loader to use to launch the applicationtry {loader = AppClassLoader.getAppClassLoader(extcl);} catch (IOException e) {throw new InternalError("Could not create application class loader", e);}//设置AppClassLoader为线程上下文类加载器,这个文章后面部分讲解Thread.currentThread().setContextClassLoader(loader);}/** Returns the class loader used to launch the main application.*/public ClassLoader getClassLoader() {return loader;}/** The class loader used for loading installed extensions.*/static class ExtClassLoader extends URLClassLoader {}/*** The class loader used for loading from java.class.path.* runs in a restricted security context.*/static class AppClassLoader extends URLClassLoader {}
源码有精简,我们可以得到相关的信息。
Launcher初始化了ExtClassLoader和AppClassLoader。
Launcher中并没有看见BootstrapClassLoader,但通过System.getProperty("sun.boot.class.path")得到了字符串bootClassPath,这个应该就是BootstrapClassLoader加载的jar包路径。
我们可以先代码测试一下sun.boot.class.path是什么内容。
System.out.println(System.getProperty("sun.boot.class.path"));
得到的结果
C:\Program Files\Java\jre1.8.0_91\lib\resources.jar;
C:\Program Files\Java\jre1.8.0_91\lib\rt.jar;
C:\Program Files\Java\jre1.8.0_91\lib\sunrsasign.jar;
C:\Program Files\Java\jre1.8.0_91\lib\jsse.jar;
C:\Program Files\Java\jre1.8.0_91\lib\jce.jar;
C:\Program Files\Java\jre1.8.0_91\lib\charsets.jar;
C:\Program Files\Java\jre1.8.0_91\lib\jfr.jar;
C:\Program Files\Java\jre1.8.0_91\classes
可以看到,这些全是JRE目录下的jar包或者是class文件。
ExtClassLoader源码
如果你有足够的好奇心,你应该会对它的源码感兴趣
/** The class loader used for loading installed extensions.*/static class ExtClassLoader extends URLClassLoader {static {ClassLoader.registerAsParallelCapable();}/*** create an ExtClassLoader. The ExtClassLoader is created* within a context that limits which files it can read*/public static ExtClassLoader getExtClassLoader() throws IOException{final File[] dirs = getExtDirs();try {// Prior implementations of this doPrivileged() block supplied// aa synthesized ACC via a call to the private method// ExtClassLoader.getContext().return AccessController.doPrivileged(new PrivilegedExceptionAction<ExtClassLoader>() {public ExtClassLoader run() throws IOException {int len = dirs.length;for (int i = 0; i < len; i++) {MetaIndex.registerDirectory(dirs[i]);}return new ExtClassLoader(dirs);}});} catch (java.security.PrivilegedActionException e) {throw (IOException) e.getException();}}private static File[] getExtDirs() {String s = System.getProperty("java.ext.dirs");File[] dirs;if (s != null) {StringTokenizer st =new StringTokenizer(s, File.pathSeparator);int count = st.countTokens();dirs = new File[count];for (int i = 0; i < count; i++) {dirs[i] = new File(st.nextToken());}} else {dirs = new File[0];}return dirs;}......}
我们先前的内容有说过,可以指定-D java.ext.dirs参数来添加和改变ExtClassLoader的加载路径。这里我们通过可以编写测试代码。
System.out.println(System.getProperty("java.ext.dirs"));
结果如下:
C:\Program Files\Java\jre1.8.0_91\lib\ext;C:\Windows\Sun\Java\lib\ext
AppClassLoader源码
/*** The class loader used for loading from java.class.path.* runs in a restricted security context.*/static class AppClassLoader extends URLClassLoader {public static ClassLoader getAppClassLoader(final ClassLoader extcl)throws IOException{final String s = System.getProperty("java.class.path");final File[] path = (s == null) ? new File[0] : getClassPath(s);return AccessController.doPrivileged(new PrivilegedAction<AppClassLoader>() {public AppClassLoader run() {URL[] urls =(s == null) ? new URL[0] : pathToURLs(path);return new AppClassLoader(urls, extcl);}});}......}
可以看到AppClassLoader加载的就是java.class.path下的路径。我们同样打印它的值。
System.out.println(System.getProperty("java.class.path"));
结果:
D:\workspace\ClassLoaderDemo\bin
这个路径其实就是当前java工程目录bin,里面存放的是编译生成的class文件。
好了,自此我们已经知道了BootstrapClassLoader、ExtClassLoader、AppClassLoader实际是查阅相应的环境属性sun.boot.class.path、java.ext.dirs和java.class.path来加载资源文件的。
看到这里我们容易知道A答案是正确的
ClassLoader翻译过来就是类加载器,普通的java开发者其实用到的不多,但对于某些框架开发者来说却非常常见。理解ClassLoader的加载机制,也有利于我们编写出更高效的代码。ClassLoader的具体作用就是将class文件加载到jvm虚拟机中去,程序就可以正确运行了。但是,jvm启动的时候,并不会一次性加载所有的class文件,而是根据需要去动态加载。想想也是的,一次性加载那么多jar包那么多class,那内存不崩溃。
看完这句话我们主动D也是正确的
ClassLoader用来加载class文件的。
系统内置的ClassLoader通过双亲委托来加载指定路径下的class和资源。
可以自定义ClassLoader一般覆盖findClass()方法。
ContextClassLoader与线程相关,可以获取和设置,可以绕过双亲委托的机制。
看完这句话我们知道B也是没问题
再来看看C
JVM在判定两个class是否相同时,不仅要判断两个类名是否相同,而且要判断是否由同一个类加载器实例加载的。
所以答案为C
我是歌谣,如有不合理之处欢迎讨论。一起学习,共同成长
阅读目录(置顶)(长期更新计算机领域知识)
阅读目录(置顶)(长期更新计算机领域知识)
阅读目录(置顶)(长期科技领域知识)
歌谣带你看java面试题
java面试题28 牛客 下面有关java classloader说法错误的是?相关推荐
- Java面试题19 牛客下面有关java的引用类型,说法正确的有?
Java面试题19下面有关java的引用类型,说法正确的有? A:对于一个对象来说,只要有强引用的存在,它就会一直存在于内存中 B:如果一个对象仅持有虚引用,那么它就和没有任何引用一样,在任何时候都可 ...
- java面试题7 牛客:关于AWT和Swing说法正确的是?
关于AWT和Swing说法正确的是? A Swing是AWT的子类 B AWT在不同操作系统中显示相同的风格 C AWT不支持事件类型,Swing支持事件模型 D Swing在不同的操作系统中显示相同 ...
- Java面试题18 牛客 假定Base b = new Derived();
Java面试题18 牛客 假定Base b = new Derived(); 调用执行b.methodOne()后,输出结果是什么? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 ...
- java面试题29 牛客 以下关于集合类ArrayList、LinkedList、HashMap描述
java面试题29 牛客 以下关于集合类ArrayList.LinkedList.HashMap描述错误的是() A HashMap实现Map接口,它允许任何类型的键和值对象,并允许将null用作键或 ...
- java面试题23 牛客ArrayLists和LinkedList的区别,下述说法正确的有?
java面试题23 牛客ArrayLists和LinkedList的区别,下述说法正确的有? A ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构. B 对于随 ...
- Java面试题 22 牛客 Java是一门支持反射的语言,基于反射为Java提供了丰富的动态性支持
Java面试题 22 牛客 Java是一门支持反射的语言,基于反射为Java提供了丰富的动态性支持,下面关于Java反射的描述,哪些是错误的:( ) A Java反射主要涉及的类如C ...
- Java面试题17 牛客 下面哪个选项正确创建socket连接?
Java面试题17 牛客 下面哪个选项正确创建socket连接? Socket s = new Socket(8080); Socket s = new Socket("192.168.1. ...
- Java面试题16 牛客 以下java程序代码,执行后的结果是()
Java面试题16 牛客 以下java程序代码,执行后的结果是() 1 2 3 4 5 6 7 8 9 10 public class Test { public static void ma ...
- Java面试题15牛客 以下关于Integer与int的区别错误的是
Java面试题15牛客 以下关于Integer与int的区别错误的是 A int是java提供的8种原始数据类型之一 B Integer是java为int提供的封装类 C int的默认值为0 D In ...
最新文章
- word分散对齐调整宽度_Word中文字很难对齐?有了这4个方法,2秒可对齐Word中所有文字...
- Quartz2D在项目中的实际使用
- 直播实录QA | 王赟Maigo分享“知识连成一片”是怎样一种体验
- ORACLE 如何查询被锁定表及释放session
- 如何将现有的非空目录转换为Git工作目录并将文件推送到远程存储库
- php ftp 分块下载,php ftp下载文件
- 【中文模板】Latex如何写中文文档
- 关于重构之Switch的处理【一】如果是有序的话,如何处理
- scrum回顾_3步开好回顾会 | IDCF FDCC认证学员作品
- 投影查询(2020-3-13)
- cfa equity
- 2017年电子设计大赛(B题 滚球控制系统)赛后总结
- 树莓派 | RSSHub+TTRSS
- 简报 | 阿里与腾讯在区块链领域必有一战
- Facebook 新一代 React 状态管理库 Recoil
- 如何锻炼出强悍的分析能力?
- 通用的WAN协议配置
- 第2部分 字符串算法(提高篇)--第2章 KMP算法1469:似乎在梦中见过的样子
- 一道小学奥数题的编程解法
- 欧冠16强抽签概率计算器
热门文章
- sql语句按月份统计查询
- error LNK2001:unresolved external symbol __imp__@ 解决方法
- 看新闻的时间用的太多了
- linux开启ping服务,Linux 云服务器禁止和开启Ping
- class对象和class文件_Class文件格式
- 数据结构c语言版总结,数据结构:C语言常见算法总结
- 咋样查mysql的url_eclipse用jdbc连接mysql数据库时,url是填什么?怎样找出地址?
- 【RK3399Pro学习笔记】九、ROS客户端Client的编程实现
- K210 / Openmv实现 大津法/Otsu最大类间方差法 自适应二值化
- C++ 高级数据类型(三)—— 指针