本文只是从 Java 的角度出发,并不涉及 Android 的类加载方式。


从上一篇解析类加载机制的文章:

我们已经知道了 ClassLoader 的委托机制。

本篇文章我们来详细分析下 ClassLoader 是如何加载 Java 类的。


一、ClassLoader 使用

流程简单说是这样的:

  • 我们用 ClassLoader 的 loadClass() 方法获取到了对应类的 class 文件;
  • 随后通过 class 文件调用 newInstance() 方法创建了对应类的实例;
  • 然后调用实例的方法;

那么其实 loadClass() 就是我们加载类的关键一步。

二、loadClass() 源码解析

从上例中,点击 loadClass() 方法,进入 ClassLoader 源码

发现实际起作用的还是 loadClass(name,false) 这个方法,我们点进去看看

源码的解释已经很清楚了,我们再来看下实际代码

用流程图可以这样概括一下

我们逐个步骤看下吧

① 保证线程安全

synchronized (getClassLoadingLock(name))

给整个 loadClass 的过程加了一把同步锁,避免了多线程共同加载相同名字的 class 的类加载问题。

② 查看是否已加载

findLoadedClass(name)

看了源码,发现查看对应名字的 class 是否已被加载是调用的 native 方法:

findLoadedClass0(name)

如果 class 已经被加载,那么就直接返回加载的 Class 文件;

如果 class 并未被加载,那么继续进行下面的步骤。

③ 查找「父'类加载器」

我们再看下全局变量 parent 的声明

所以,在加载类时,起初 parent 不为 null,所以会调用

parent.loadClass(name,false)

依次往父级上推,直到 parent 为 null,即追溯到的「父'类加载器」是

BootStrap,则会调用

findBootstrapClassOrNull(name)

方法,我们来看下这个方法的定义

这个方法会返回一个“被 bootstrap 加载过的类,如果没有找到,则会返回 null ”

而真正的逻辑处理也是一个 native 方法:

findBootstrapClass(name)

如果这个方法返回值不为 null ,loadClass 流程会进入:

parent.loadClass(name, false)

阶段,依次往父级上推,直到出现下方情况之一

  • 加载成功,返回加载好的类
  • 加载失败,返回 null
  • 加载异常,抛出 ClassNotFoundException 异常

则结束此过程。

④ 如果加载失败,返回为 null,则会调用:

findClass(name)

即如果我们没有自定义类加载器,默认则会抛出

ClassNotFoundException 异常。

ok ,这样整个过程就结束了。

我们可以看到,整个 loadClass() 的方法会有两种情况:

  • 加载成功,返回加载好的类
  • 加载异常,抛出 ClassNotFoundException 异常

三、单纯了解了 ClassLoader 中的 loadClass() 不够,我们来自定义一个类加载器吧

我的例子的思路大致是:

① 创建一个需要被自定义的 ClassLoader 加载的 java 文件,并编译成为 class 文件

很简单,就是打印一句话,但此例是我们要创建 java 文件的基类。

下面是我们的需要加载的 java 文件,即上面基类的子类。

运行,得到 class 文件

红框内即我们得到的class 文件

② 在我们工程目录下创建一个新的目录,用来存放我们创建好的 class 文件

③ 编写我们的自定义 ClassLoader 文件

对,没有可扩展性,路径都是定的。

因为上文中我们解析 loadClass() 方法的源码时,得知我们需要重写

findClass

方法,所以这里就重写了下,主要功能就是找到我们放到 myclasses 文件夹下的 class 文件,并且调用 defineClass 方法去解析出来。

④ 创建运行类,查看类加载器的加载规则

打印结果是

我们发现,同样是通过 myClassLoader 的实例加载的类,但是当我们加载

MyClassLoaderTest 时:

Class loadClass = classLoader.loadClass("com.guaju.classloadertest.MyClassLoaderTest");

真正的类加载器是 AppClassLoader

而当我们加载 PrintUtil 时:

 Class> loadClass = myClassLoader.loadClass("PrintUtil");

真正的类加载器是 MyClassLoader。

当我们修改 PrintUtils 的加载方式时

真正的类加载器也是 AppClassLoader

总结得到这两点:

  • 自定义类加载器时,如果传入完整类名,会优先使用系统类加载器去加载类,如果系统类加载器找不到该类,则会调用自定义的类加载器。
  • 自定义类加载器时,需要使用 findClass 去定位需要加载的类,读取并调用 defineClass 方法去解析类

好了,本篇完~~~

后续会继续针对 Android 项目的类加载进行解析,如果有兴趣想继续看,点个关注吧~

dll已加载但找不到入口点dllregisterserver_Java 是如何加载类的?相关推荐

  1. dll侧加载_win7系统开机提示xxxdll模块已加载但找不到入口点的解决方法

    很多小伙伴都遇到过win7系统开机提示xxxdll模块已加载但找不到入口点的困惑吧,一些朋友看过网上零散的win7系统开机提示xxxdll模块已加载但找不到入口点的处理方法,并没有完完全全明白win7 ...

  2. 计算机进管理提示找不到入口,win10系统开机提示xxxdll模块已加载但找不到入口点的教程...

    有关win10系统开机提示xxxdll模块已加载但找不到入口点的操作方法想必大家有所耳闻.但是能够对win10系统开机提示xxxdll模块已加载但找不到入口点进行实际操作的人却不多.其实解决win10 ...

  3. kernel32.dll已加载但找不到入口点_关键词分析法和工具,关键词分析包括哪几个方面(已帮助1376人)...

    内容导读关键词分析是极其重要的环节,如果关键词分析做好了,优化工作就能事半功倍.大家在做关键词分析的时候,可以参考本文提到的这些方面,应该能够得到很多有用的启示和指导. 做网站优化或者是百度竞价等,分 ...

  4. 计算机缺失gfesdk.dll,xapofx1_5.dll 已加载但找不到入口点dellregisterserver

    满意答案 andjpg 2013.09.08 采纳率:43%    等级:12 已帮助:13587人 (1)运行输入msconfig回车,打开系统配置实用程序,在启动项目中查找一个名为"** ...

  5. 计算机中丢失inetcomm,模块inetcomm.dll已加载,但找不到入口点DllRegisterServer

    推荐答案 (1)运行输入msconfig回车,打开系统配置实用程序,在启动项目中查找一个名为"****.dll",如果有将它前面的钩去掉,然后按应用确定(如果没有跳过). (2)运 ...

  6. 【已解决】steamclient64.dll已加载,但找不到入口点

    steamclient64.dll是电脑内十分重要的文件,它的丢失易导致游戏.应用软件等程序运行出现错误,致使程序无法正常运行,它的解决办法也是非常简单的,只要下载好steamclient64.dll ...

  7. dll已加载但找不到入口点DLLRegisterServer

    别自己瞎折腾了. 解决方案: 360软件管家安装""微软常用运行库合集"" 即可.

  8. 模块mshtml.dll已加载,但找不到入口点DllRegisterServer(随手笔记)

    模块mshtml.dll已加载,但找不到入口点DllRegisterServer 通常在运行中注册动态库文件:Microsoft.Office.Interop.Word.dll (按回车键执行命令)都 ...

  9. 计算机丢失api-ms-win-core-sysinfo-l1-2-0.dll ;模块找不到入口点DLLRegisterServer,unknown debugger type no engine

    在使用qt和vs的过程中遇到下述情况,在此记录解决办法 (1)无法启动程序,因为计算机中丢失api-ms-win-core-sysinfo-l1-2-0.dll (2)模块已加载,但找不到入口点DLL ...

最新文章

  1. 动态半导体ram依据什么存储信息_都是存储器,但RAM、ROM、闪存、硬盘怎么分?...
  2. 第111天:Ajax之jQuery实现方法
  3. [De1CTF2019]Babylfsr
  4. const关键字的作用?
  5. 《Hive编程指南》14.3 投影变换的实践出错原因分析
  6. 苹果中国大出血! AirPods 2免费送了
  7. spring mvc tutorial
  8. MyEclipse持续性开发教程:用JPA和Spring管理数据(三)
  9. 【整理】牛客网编程题前端篇(较难难度)
  10. PHP 遍历文件夹及文件类及处理类
  11. ccs 中文乱码_关于字符集和乱码的思考
  12. android 编译 libjpeg-turbo,编译Android环境的libjpeg-turbo
  13. 操作系统学习之windows发展史
  14. RTP直播分发服务器集群方案
  15. newLISP你也行 --- 字符串
  16. 有关爬虫浏览量的问题
  17. 最新的100个微信小程序-极乐Store
  18. 关于java的毕业设计_我的java毕业设计之路回顾
  19. macOS 开发 - XPC
  20. 【fast ICA】基于fast ICA算法的去除伪迹matlab仿真

热门文章

  1. SAP 电商云 Spartacus UI 同 SAP Customer Data Cloud 集成运行时的 api
  2. 如何创建最简单的 ABAP 数据库表,以及编码从数据库表中读取数据 (上)
  3. 如何在 SAP Commerce Cloud Portal 构建和部署 SAP Spartacus Storefront
  4. 如何将SAP API Hub 上提供的工作流导入到 SAP BTP 上
  5. SAP Spartacus产品明细页面用Observable显示产品名称
  6. 一个有用的Chrome扩展应用:SAP UI5 Inspector
  7. 修改Hybris Administration console管理员默认登录密码
  8. OData Console in C4C and Gateway Client in CRM Fiori
  9. var a = b = 5 and use strict mode
  10. 如何使用Marketing Cloud的扩展字段作为搜索条件进行搜索