[Java类加载器]Java中classLoader浅析.
[Java类加载器]Java中classLoader浅析.
本文为在公司内部TD上写的一篇小文, 主要讲解java中classLoader基础知识, 现在拿来这里分享一下.
一、问题
请在Eclipse中新建如下类,并运行它:
![](/assets/blank.gif)
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 }
![](/assets/blank.gif)
你能猜到它的运行如果吗? 不错,就是如下这个样子!
错误: 在类 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层次结构
请执行如下程序:
![](/assets/blank.gif)
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 }
![](/assets/blank.gif)
它的输出是:
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核心类。
[Java类加载器]Java中classLoader浅析.相关推荐
- 深入理解Java类加载器:Java类加载原理解析
http://blog.csdn.net/zhoudaxia/article/details/35824249 1 基本信息 每个开发人员对java.lang.ClassNotFoundExcetpi ...
- 【java】 Java 类加载器 破坏双亲委派
1.概述 深入探讨 Java 类加载器 Java双亲委派模型:为什么要双亲委派?如何打破它?破在哪里? Java中的双亲委派机制以及如何打破
- Java中classLoader浅析
转载自 Java中classLoader浅析 本文为在公司内部TD上写的一篇小文, 主要讲解java中classLoader基础知识, 现在拿来这里分享一下. 一.问题 请在Eclipse中新建如下 ...
- Java类加载器详解
Java虚拟机中的类加载有三大步骤:,链接,初始化.其中加载是指查找字节流(也就是由Java编译器生成的class文件)并据此创建类的过程,这中间我们需要借助类加载器来查找字节流. Java虚拟机默认 ...
- JVM之Java类加载器
前言 通过对Java类加载机制的了解,可以知道大概流程和各自的功能.其中类加载部分的功能是把类的Class文件读入内存,并创建java.lang.Class对象.这部分功能是由类加载器完成的. 1.类 ...
- 深入探讨 Java 类加载器
深入探讨 Java 类加载器 类加载器(class loader)是 Java™中的一个很重要的概念.类加载器负责加载 Java 类的字节代码到 Java 虚拟机中.本文首先详细介绍了 Java 类加 ...
- java类加载器、双亲委派、沙箱安全机制全都让你整明白(三万字,收藏慢慢啃)
目录 一.概述 1.类加载的分类 2.类加载器的必要性 3.命名空间 4.类加载机制的基本特征 二.类加载器的分类 1.引导类加载器 2.扩展类加载器 3.系统类加载器 4.用户自定义类加载器 三.测 ...
- 80070583类不存在_结合JVM源码谈Java类加载器
一.前言 之前文章 加多:ClassLoader解惑zhuanlan.zhihu.com 从Java层面讲解了Java类加载器的原理,这里我们结合JVM源码在稍微深入讲解下. 二.Java类加载器的 ...
- java类加载器_类加载器
回顾一下类加载过程 类加载过程:加载->连接->初始化.连接过程又可分为三步:验证->准备->解析. 一个非数组类的加载阶段(加载阶段获取类的二进制字节流的动作)是可控性最强的 ...
最新文章
- SGML与HTML、XML
- 怎样解决xcode里开发cocos2dx改动lua脚本后不刷新的问题
- Kubernetes安全之鉴权
- VTK:几何对象之ConvexPointSet
- python cnn模型_ZfNet解卷积:可视化CNN模型( PythonCode可视化Cifar10)
- 分布式会话拦截器2 - 会话判断
- ABAP Netweaver和git的快捷方式
- r语言c5.0决策树算法参数,决策树算法CART、C5.0的R语言实现——(三)
- Web前端开发面试考点指南
- Linux 链接详解----静态链接实例分析
- JSK-388 等差数列【入门】
- 谷歌浏览器没有添加flash选项
- Oracle JDK 终于免费了!网友:are you sure?
- 用c++编写别踩白块儿小游戏
- Excel拆分单元格内容(把一个单元格的内容拆分到多列)
- 设置来电铃声android,设置默认来电铃声 android
- 5D论文PMF及改进
- 饿了么table排序
- Apache的Order Allow,Deny 配置详解
- SpringBoot整合Thymleaf实现页面静态化