Java中ClassLoader浅析.
一、问题
请在Eclipse中新建如下类,并运行它:
1 package java.lang; 2 3 public class Long { 4 public static void main(String[] args) { 5 System.out.println("Hi, i am here"); 6 } 7 }
你能猜到它的运行如果吗? 不错,就是如下这个样子!
错误: 在类 java.lang.Long 中找不到 main 方法, 请将 main 方法定义为: |
为什么呢,明明我在Long方法类中定义了main方法,为什么说main方法没有定义呢?
本文将解决以上问题出现的原因。
二、ClassLoader的作用
我们都知道java程序写好以后是以.java(文本文件)的文件存在磁盘上,然后,我们通过(bin/javac.exe)编译命令把.java文件编译成.class文件(字节码文件),并存在磁盘上。但是程序要运行,首先一定要把.class文件加载到JVM内存中才能使用的,我们所讲的classLoader,就是负责把磁盘上的.class文件加载到JVM内存中,如下图所示:
你可以认为每一个Class对象拥有磁盘上的那个.class字节码内容,每一个class对象都有一个getClassLoader()方法,得到是谁把我从.class文件加载到内存中变成Class对象的。
三、ClassLoader层次结构
请执行如下程序:
1 public class Test {2 public static void main(String[] args) {3 ClassLoader classLoader = Test.class.getClassLoader();4 System.out.println(classLoader);5 6 ClassLoader classLoader1 = classLoader.getParent();7 System.out.println(classLoader1);8 9 ClassLoader classLoader2 = classLoader1.getParent(); 10 System.out.println(classLoader2); 11 } 12 }
它的输出是:
sun.misc.Launcher$AppClassLoader@2a139a55
sun.misc.Launcher$ExtClassLoader@7852e922
null
得到了 classLoader2就是null值了。这里其实有三个类加载器:
(1): 根类加载器(null)
它是由本地代码(c/c++)实现的,你根本拿不到他的引用,但是他实际存在,并且加载一些重要的类,它加载(%JAVA_HOME%\jre\lib),如rt.jar(runtime)、i18n.jar等,这些是Java的核心类。
(2): 扩展类加载器(ExtClassLoader)
虽说能拿到,但是我们在实践中很少用到它,它主要加载扩展目录下的jar包, %JAVA_HOME%\lib\ext
(3): 应用类加载器(AppClassLoader)
它主要加载我们应用程序中的类,如Test,或者用到的第三方包,如jdbc驱动包等。
这里的父类加载器与类中继承概念要区分,它们在class定义上是没有父子关系的。
四、Class加载时调用类加载器的顺序
当一个类要被加载时,有一个启动类加载器和实际类加载器的概念,这个概念请看如下分析
如上面的Test.class要进行加载时,它将会启动应用类加载器进行加载Test类,但是这个应用类加载器不会真正去加载他,而是会调用看是否有父加载器,结果有,是扩展类加载器,扩展类加载器也不会直接去加载,它看自己是否有父加载器没,结果它还是有的,是根类加载器。
所以这个时候根类加载器就去加载这个类,可在%JAVA_HOME%\jre\lib下,它找不到com.wangmeng.Test这个类,所以他告诉他的子类加载器,我找不到,你去加载吧,子类扩展类加载器去%JAVA_HOME%\lib\ext去找,也找不着,它告诉它的子类加载器 AppClassLoader,我找不到这个类,你去加载吧,结果AppClassLoader找到了,就加到内存中,并生成Class对象。
这个时间时候启动类加载器(应用类加载器)和实际类加载器(应用类加载器)是同一个.
这就是Java中著名的委托加载机制,看如下图:
我们再来看一下 java.lang.Long的加载,按上面分析,应该是由根类加载器加载得到的,此时启动类加载器是应用类加载器,但实际类加载器是根类加载器。
所以回到我们最开始那个问题,没有main方法是因为执行的根本不是我们自己写的类,执行的是java核心中的那个Long类,当然没有main方法了。 这样就防止我们应用中写的类覆盖掉java核心类。
转载于:https://www.cnblogs.com/kexianting/p/8526998.html
Java中ClassLoader浅析.相关推荐
- Java中classLoader浅析
转载自 Java中classLoader浅析 本文为在公司内部TD上写的一篇小文, 主要讲解java中classLoader基础知识, 现在拿来这里分享一下. 一.问题 请在Eclipse中新建如下 ...
- [Java类加载器]Java中classLoader浅析.
[Java类加载器]Java中classLoader浅析. 本文为在公司内部TD上写的一篇小文, 主要讲解java中classLoader基础知识, 现在拿来这里分享一下. 一.问题 请在Eclips ...
- android classloader的功能和工作模式,Android中ClassLoader和java中ClassLoader有什么关系和不同...
一.Java中的ClassLoader是什么? 当写好一个Java应用程序,程序都是由若干个.class类文件组织而成的,当程序在运行时,即会调用该程序的一个入口函数来调用系统的相关功能,而这些功能都 ...
- java中new_浅析Java中的 new 关键字
java的new关键字想必大家都知道这是实例化一个对象.没错,也是为新对象分配内存空间. 比如new MyDate(22,7,1964)这样一个案例,他的完成需要四部: 一.为新对象分配内存空间,将M ...
- Java基础—ClassLoader的理解
##默认的三个类加载器 Java默认是有三个ClassLoader,按层次关系从上到下依次是:- Bootstrap ClassLoader- Ext ClassLoader- System Clas ...
- java classloader_Java Classloader原理分析
类的加载过程指通过一个类的全限定名来获取描述此类的二进制字节流,并将其转化为方法区的数据结构,进而生成一个java.lang.Class对象作为方法区这个类各种数据访问的入口.这个过程通过Java中的 ...
- Java中的Unsafe在安全领域的一些应用总结和复现
Python微信订餐小程序课程视频 https://edu.csdn.net/course/detail/36074 Python实战量化交易理财系统 https://edu.csdn.net/cou ...
- Java中的ClassLoader和SPI机制
深入探讨 Java 类加载器 成富是著名的Java专家,在IBM技术网站发表很多Java好文,也有著作. 线程上下文类加载器 线程上下文类加载器(context class loader)是从 JDK ...
- 浅析Java中的final关键字
浅析Java中的final关键字 谈到final关键字,想必很多人都不陌生,在使用匿名内部类的时候可能会经常用到final关键字.另外,Java中的String类就是一个final类,那么今天我们就来 ...
最新文章
- 如何将Dictionary绑定到Repeater?
- vuejs和webpack项目(VueComponent)初尝试——瀑布流组件
- jQuery 表格插件
- 大数据项目一般金额多少_大数据分析师年薪一般多少?学什么专业才能从事大数据?...
- gperf工具的使用
- 数学之路(2)-数据分析-R基础(5)
- 【机器学习基础】关于Scikit-Learn,你不一定知道的10件事
- Spring Security——OAuth 2.0 Client自动配置源代码分析
- 快醒醒,C# 9 中又来了一堆关键词 init,record,with
- c++ new delete
- 杭电1210 Eddy's 洗牌问题
- C++数据结构与算法(九) 树,优先级队列,最大堆的实现
- 那些开源程序中让人叹为观止的代码 - 1 浏览器特性判断
- Centos 7.9系统安装网卡驱动
- 健康体检信息系统源码、医院体检源码 医院管理系统源码
- win10热点开启后,手机可以连上热点但无法连接网络
- html的nofollow标签,HTML中的A标签的nofollow属性解读
- 渗透测试流程(基础理论)
- Android 屏蔽锁屏界面上的通知显示
- 【机房收费个人版】SqlHelper