我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Java的ClassLoader机制是什么

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Java的ClassLoader机制是什么

本篇内容介绍了“Java的ClassLoader机制是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

JVM在加载类的时候,都是通过ClassLoader的loadClass()方法来加载class的,loadClass(String name)方法:

使用的是双亲委托模式:

jvm启动时,会启动jre/rt.jar里的类加载器:bootstrap classloader,用来加载java核心api;然后启动扩展类加载器ExtClassLoader加载扩展类,并加载用户程序加载器AppClassLoader,并指定ExtClassLoader为他的父类;

当类被加载时,会先检查在内存中是否已经被加载,如果是,则不再加载,如果没有,再由AppClassLoader来加载,先从jar包里找,没有再从classpath里找;

如果自定义loader类,就会存在这命名空间的情况,不同的加载器加载同一个类时,产生的实例其实是不同的;

Java代码

public Class<?> loadClass(String name) throws ClassNotFoundException { return loadClass(name, false); }  public Class<?> loadClass(String name) throws ClassNotFoundException { return loadClass(name, false); }

loadClass(String name)方法再调用loadClass(String name, boolean resolve)方法:

◆ name - 类的二进制名称

◆ resolve - 如果该参数为 true,则分析这个类

Java代码

protected synchronized Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException { // First, check if the class has already been loaded //JVM 规范规定ClassLoader可以在缓存保留它所加载的Class,如果一个Class已经被加载过,则直接从缓存中获取 Class c = findLoadedClass(name); if (c == null) { try { if (parent != null) { c = parent.loadClass(name, false); } else { c = findBootstrapClass0(name); } } catch (ClassNotFoundException e) { // If still not found, then invoke findClass in order // to find the class. c = findClass(name); } } if (resolve) { resolveClass(c); } return c; }  protected synchronized Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException { // First, check if the class has already been loaded //JVM 规范规定ClassLoader可以在缓存保留它所加载的Class,如果一个Class已经被加载过,则直接从缓存中获取 Class c = findLoadedClass(name); if (c == null) { try { if (parent != null) { c = parent.loadClass(name, false); } else { c = findBootstrapClass0(name); } } catch (ClassNotFoundException e) { // If still not found, then invoke findClass in order // to find the class. c = findClass(name); } } if (resolve) { resolveClass(c); } return c; }

如果ClassLoader并没有加载这个class,则调用findBootstrapClass0:

Java代码

private Class findBootstrapClass0(String name) throws ClassNotFoundException { check(); if (!checkName(name)) throw new ClassNotFoundException(name); return findBootstrapClass(name); }  private Class findBootstrapClass0(String name) throws ClassNotFoundException { check(); if (!checkName(name)) throw new ClassNotFoundException(name); return findBootstrapClass(name); }

该方法会调用check()方法来判断这个类是否已经初始化,并且通过checkName(name)来判断由name指定的这个类是否存在***调用findBootstrapClass(name):

Java代码

private native Class findBootstrapClass(String name) throws ClassNotFoundException;  private native Class findBootstrapClass(String name) throws ClassNotFoundException;

而这个findBootstrapClass方法是一个native方法,这是我们的root loader,这个载入方法并非是由JAVA所写,而是C++写的,它会最终调用JVM中的原生findBootstrapClass方法来完成类的加载。

如果上面两个都找不到,则使用findClass(name)来查找指定类名的Class:

Java代码

protected Class<?> findClass(String name) throws ClassNotFoundException { throw new ClassNotFoundException(name); }  protected Class<?> findClass(String name) throws ClassNotFoundException { throw new ClassNotFoundException(name); }

JDK5.0中的说明:

使用指定的二进制名称查找类。此方法应该被类加载器的实现重写,该实现按照委托模型来加载类。在通过父类加载器检查所请求的类后,此方法将被 loadClass 方法调用。默认实现抛出一个ClassNotFoundException。

所以,我们在自定义类中,只需要重写findClass()即可。

MyClassLoader类:

Java代码

public class MyClassLoader extends ClassLoader { private String fileName;  public MyClassLoader(String fileName) { this.fileName = fileName; }  protected Class<?> findClass(String className) throws ClassNotFoundException { Class clazz = this.findLoadedClass(className); if (null == clazz) { try { String classFile = getClassFile(className); FileInputStream fis = new FileInputStream(classFile); FileChannel fileC = fis.getChannel(); ByteArrayOutputStream baos = new ByteArrayOutputStream(); WritableByteChannel outC = Channels.newChannel(baos); ByteBuffer buffer = ByteBuffer.allocateDirect(1024); while (true) { int i = fileC.read(buffer); if (i == 0 || i == -1) { break; } buffer.flip(); outC.write(buffer); buffer.clear(); } fis.close(); byte[] bytes = baos.toByteArray();  clazz = defineClass(className, bytes, 0, bytes.length); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } return clazz; } private byte[] loadClassBytes(String className) throws ClassNotFoundException { try { String classFile = getClassFile(className); FileInputStream fis = new FileInputStream(classFile); FileChannel fileC = fis.getChannel(); ByteArrayOutputStream baos = new ByteArrayOutputStream(); WritableByteChannel outC = Channels.newChannel(baos); ByteBuffer buffer = ByteBuffer.allocateDirect(1024); while (true) { int i = fileC.read(buffer); if (i == 0 || i == -1) { break; } buffer.flip(); outC.write(buffer); buffer.clear(); } fis.close(); return baos.toByteArray(); } catch (IOException fnfe) { throw new ClassNotFoundException(className); } } private String getClassFile(String name) { StringBuffer sb = new StringBuffer(fileName); name = name.replace('.', File.separatorChar) + ".class"; sb.append(File.separator + name); return sb.toString(); } }  public class MyClassLoader extends ClassLoader { private String fileName;  public MyClassLoader(String fileName) { this.fileName = fileName; }  protected Class<?> findClass(String className) throws ClassNotFoundException { Class clazz = this.findLoadedClass(className); if (null == clazz) { try { String classFile = getClassFile(className); FileInputStream fis = new FileInputStream(classFile); FileChannel fileC = fis.getChannel(); ByteArrayOutputStream baos = new ByteArrayOutputStream(); WritableByteChannel outC = Channels.newChannel(baos); ByteBuffer buffer = ByteBuffer.allocateDirect(1024); while (true) { int i = fileC.read(buffer); if (i == 0 || i == -1) { break; } buffer.flip(); outC.write(buffer); buffer.clear(); } fis.close(); byte[] bytes = baos.toByteArray();  clazz = defineClass(className, bytes, 0, bytes.length); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } return clazz; } private byte[] loadClassBytes(String className) throws ClassNotFoundException { try { String classFile = getClassFile(className); FileInputStream fis = new FileInputStream(classFile); FileChannel fileC = fis.getChannel(); ByteArrayOutputStream baos = new ByteArrayOutputStream(); WritableByteChannel outC = Channels.newChannel(baos); ByteBuffer buffer = ByteBuffer.allocateDirect(1024); while (true) { int i = fileC.read(buffer); if (i == 0 || i == -1) { break; } buffer.flip(); outC.write(buffer); buffer.clear(); } fis.close(); return baos.toByteArray(); } catch (IOException fnfe) { throw new ClassNotFoundException(className); } } private String getClassFile(String name) { StringBuffer sb = new StringBuffer(fileName); name = name.replace('.', File.separatorChar) + ".class"; sb.append(File.separator + name); return sb.toString(); } }

该类中通过调用defineClass(String name, byte[] b, int off, int len)方法来定义一个类:

Java代码

protected final Class<?> defineClass(String name, byte[] b, int off, int len) throws ClassFormatError { return defineClass(name, b, off, len, null); }  protected final Class<?> defineClass(String name, byte[] b, int off, int len) throws ClassFormatError { return defineClass(name, b, off, len, null); }

注:MyClassLoader加载类时有一个局限,必需指定.class文件,而不能指定.jar文件。该类中的大部分代码是从网上搜索到的,是出自一牛人之笔,只是不知道原帖在哪,希望不会被隐藏。

MainClassLoader类:

Java代码

public class MainClassLoader { public static void main(String[] args) { try { MyClassLoader tc = new MyClassLoader("F:\\OpenLib\\"); Class c = tc.findClass("Test"); c.newInstance(); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } } }  public class MainClassLoader { public static void main(String[] args) { try { MyClassLoader tc = new MyClassLoader("F:\\OpenLib\\"); Class c = tc.findClass("Test"); c.newInstance(); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } } }

***是一个简单的Test测试类:

Java代码

public class Test { public Test() { System.out.println("Test"); } public static void main(String[] args) { System.out.println("Hello World"); } }

“Java的ClassLoader机制是什么”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注编程网网站,小编将为大家输出更多高质量的实用文章!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Java的ClassLoader机制是什么

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Java的ClassLoader机制是什么

本篇内容介绍了“Java的ClassLoader机制是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!JVM在加载类的时候,都是通过Cla
2023-06-17

java classloader的工作机制是什么

Java的ClassLoader是Java虚拟机(JVM)的一个重要组成部分,它主要负责加载Java类文件并把字节码文件转换成运行时的Class对象。ClassLoader的工作机制可以简单地描述为以下几个步骤:寻找类文件:ClassLo
java classloader的工作机制是什么
2024-04-09

java classloader的工作机制是什么

Java类加载器是一种分层系统,动态加载类定义。它包含三个主要类加载器:Bootstrap、扩展和系统,遵循分层和委托机制。每个加载器在自己的范围内加载类,并委托给父加载器加载不在其范围内的类。Java采用双亲委派模型,保证加载优先级和类隔离。开发人员还可以创建自定义类加载器以修改类加载行为。
java classloader的工作机制是什么
2024-04-10

Java的ClassLoader是什么

本文小编为大家详细介绍“Java的ClassLoader是什么”,内容详细,步骤清晰,细节处理妥当,希望这篇“Java的ClassLoader是什么”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。ClassLoad
2023-06-16

java classloader的使用方法是什么

Java ClassLoader是Java虚拟机(JVM)的一个重要组成部分,用于加载Java类文件。ClassLoader负责将编译后的Java类文件加载到内存中,并在运行时实例化这些类。使用ClassLoader可以实现动态加载类、实现
java classloader的使用方法是什么
2024-04-09

java classloader的使用方法是什么

Java类加载器使用方法Java类加载器负责加载、链接和初始化类,确保应用程序加载正确的类并防止冲突。使用步骤:加载:从存储库读取类二进制表示。链接:连接类和解析符号引用。初始化:调用静态初始化程序。类型:引导类加载器:加载核心类库。扩展类加载器:加载扩展类路径中的类。系统类加载器:加载系统类路径中的类。自定义类加载器:由开发人员创建。使用:使用默认类加载器。创建自定义类加载器。设置类加载器。最佳实践:使用默认类加载器。仅在需要时创建自定义类加载器。考虑类加载委托的性能影响。测试自定义类加载器的行为。
java classloader的使用方法是什么
2024-04-12

Java的ClassLoader有什么用

这篇文章主要介绍“Java的ClassLoader有什么用”,在日常操作中,相信很多人在Java的ClassLoader有什么用问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Java的ClassLoader有
2023-06-17

java中的classloader有什么功能

JavaClassLoader功能ClassLoader是Java虚拟机中负责加载、链接和初始化Java类的核心组件,其功能包括:类加载:加载.class文件,构建类型层次结构。类验证:确保加载的类符合规范,防止安全漏洞。依赖管理:按正确顺序加载和链接类。安全保护:控制对敏感资源的访问。可扩展性:允许创建自定义类加载器以满足特定需求。ClassLoader有四种主要类型:启动类加载器、扩展类加载器、系统类加载器和自定义类加载器,各有其加载位置和功能。通过调用loadClass()方法或创建自定义类加载器,
java中的classloader有什么功能
2024-04-11

Java的SPI机制是什么

本篇内容介绍了“Java的SPI机制是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!SPI的全名为Service Provider In
2023-06-17

Java中的SPI机制是什么

这篇文章主要介绍“Java中的SPI机制是什么”,在日常操作中,相信很多人在Java中的SPI机制是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Java中的SPI机制是什么”的疑惑有所帮助!接下来,请跟
2023-07-05

java的多态机制是什么

Java多态的实现机制是父类或接口定义的引用变量可以指向子类或实现类的实例对象,而程序调用的方法在运行期才动态绑定,就是引用变量所指向的具体实现对象的方法,也就是内存里正在运行的那个对象的方法,而不是引用变量的类型中定义的方法。本质上多态分两种: ·编译
java的多态机制是什么
2015-01-09

Java中的锁机制是什么

今天小编给大家分享一下Java中的锁机制是什么的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。Java中的锁机制是保证多线程并
2023-07-05

Java 类加载机制究竟是什么?(Java类加载机制是什么)

在Java编程中,类加载机制是一个非常重要的概念,它对于Java程序的运行和性能有着深远的影响。本文将详细介绍Java类加载机制的工作原理、过程以及相关的重要概念。一、类加载机制的概述类加载机制是Java虚拟机(
Java 类加载机制究竟是什么?(Java类加载机制是什么)
Java2024-12-22

JAVA的classloader怎么编写

今天小编给大家分享一下JAVA的classloader怎么编写的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。什么是 Clas
2023-06-03

java多态机制是什么

java多态机制是什么java中实现多态的机制是依靠父类或接口的引用指向子类。从而实现了一个对象多种形态的特性。其中父类的引用是在程序运行时动态的指向具体的实例,调用该引用的方法时,不是根据引用变量的类型中定义的方法来运行,而是根据具体的实例的方法。概念多态就
java多态机制是什么
2020-02-04

什么是java反射机制

java:“一切即对象”,感觉java语言本身在不断践行着这句话。java反射机制的基础来源于一个Class类,我们可以通过这个类里面的方法来对每一个类进行读取、实例化等。对象表示或封装一些数据。一个类被加载后,jvm会创建一个对应该类的Class对象(一个类
什么是java反射机制
2019-08-24

java反射机制是什么

这篇文章主要介绍了java反射机制是什么,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。Java的特点有哪些Java的特点有哪些1.Java语言作为静态面向对象编程语言的代表,
2023-06-14

什么是Java回调机制

这篇文章主要讲解了“什么是Java回调机制”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“什么是Java回调机制”吧!一、回调回调分为同步回调和异步回调, 假如以买彩票的场景来模拟, 我买彩票
2023-06-20

Java RMI机制的原理是什么

本篇内容主要讲解“Java RMI机制的原理是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Java RMI机制的原理是什么”吧!Java RMIJava RMI之HelloWorld篇Ja
2023-06-20

Java类的加载机制是什么

这篇文章主要讲解了“Java类的加载机制是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Java类的加载机制是什么”吧!1、什么是类的加载类的加载指的是将类的.class文件中的二进制数
2023-06-17

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录