热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

29、es6中的class类的深入理解_类加载的表现形式

java中的类是动态加载的,我们先看一下我们常用的类加载方式,先有一个感性的认识,才能进一步深入讨论,类加载无非就是下面三种方式。clas
f1061feb940f99d0314584477fbe874d.png

java中的类是动态加载的,我们先看一下我们常用的类加载方式,先有一个感性的认识,才能进一步
深入讨论,类加载无非就是下面三种方式。
class A{}
class B{}
class C{}
public class Loader{
public static void main(String[] args) throws Exception{
Class aa=A.class;
Class bb=Class.forName("B");
Class cc=ClassLoader.getSystemClassLoader().loadClass("C");
}
}
我们先看.class字面量方式,很多人可能不知道这种方式,因为这种用法不是一般java语法。
通过javap我们可以发现,这种方式的大致等价于定义了一个静态成员变量
static Class class$0;(后面的编号是增长的)
你可以试图再定义一个 static Class class$0,应该会收到一个编译错误(重复定义)。
Class aa=A.class;
就相当于
if(class$0==null){
try{
Class.forName("A");
}
cacth(ClassNotFoundException e){
throw new NoClassDefFoundError(e);
}
}
Class aa=class$0;
可以很清楚的看到,这种类的字面量定义其实不是加载类的方式,而是被编译器处理了,实质
上是使用了Class.forName方法,但是使用这种方式有一个很大的好处就是不用处理异常,因为
编译器处理的时候如果找不到类会抛出一个NoClassDefFoundError。也许你觉得需要处理
ClassNotFoundException这种异常,事实上99%的情况下我们可以把这种异常认为是一个错误。
所以大部分情况我们使用这种方式会更简洁。
最常用的方式就是Class.forName方式了,这也是一个通用的上层调用。这个方法有两个重载,
可能很多人都忽略了第二个方法。
public static Class forName(String name) throws ClassNotFoundException
public static Class forName(String name, boolean initialize,ClassLoader loader) throws ClassNotFoundException
第二个方法后面多了两个参数,第二个参数表示是否初始化,第三个参数为指定的类加载器。
在上面的例子中:
Class bb=Class.forName("B");等价于
Class bb=Class.forName("B",true,Loader.class.getClassLoader());
这里要详细说一下这个类的初始化这个参数,如果这个参数为false的话,
类中的static成员不会被初始化,static语句块也不会被执行。
也就是类虽然被加载了,但是没有被初始化,不过在第一次使用时仍然会初始化。
所以我们有时候会看到Class.forName("XXX").newInstance()这样的语句,为什么这里要创建一个
不用的实例呢?不过是为了保证类被初始化(兼容以前的系统)。
其实第二个方法是比较难用的,需要指定类加载器,如果不指定而且又没有安装安全管理器的化,
是无法加载类的,只要看一下具体的实现就明白了。
最本质的方式当然是直接使用ClassLoader加载了,所有的类最终都是通过ClassLoader加载的,
Class cc=ClassLoader.getSystemClassLoader().loadClass("C");
这里通过使用系统类加载器来加载某个类,很直接的方式,但是很遗憾的是通过这种方式加载类,
类是没有被初始化的(也就是初始化被延迟到真正使用的时候).不过我们也可以借鉴上面的经验,加载
后实例化一个对象Class cc=ClassLoader.getSystemClassLoader().loadClass("C").newInstance()。
这里使用了系统类加载器,也是最常用的类加载器,从classpath中寻找要加载的类。
java中默认有三种类加载器:引导类加载器,扩展类加载器,系统类加载器。
java中的类加载有着规范的层次结构,如果我们要了解类加载的过程,需要明确知道哪个类被谁
加载,某个类加载器加载了哪些类等等,就需要深入理解ClassLoader的本质。
以上只是类加载的表面的东西,我们还将讨论深层次的东西。



推荐阅读
  • 标题: ... [详细]
  • 本文介绍了Java高并发程序设计中线程安全的概念与synchronized关键字的使用。通过一个计数器的例子,演示了多线程同时对变量进行累加操作时可能出现的问题。最终值会小于预期的原因是因为两个线程同时对变量进行写入时,其中一个线程的结果会覆盖另一个线程的结果。为了解决这个问题,可以使用synchronized关键字来保证线程安全。 ... [详细]
  • 本文介绍了RxJava在Android开发中的广泛应用以及其在事件总线(Event Bus)实现中的使用方法。RxJava是一种基于观察者模式的异步java库,可以提高开发效率、降低维护成本。通过RxJava,开发者可以实现事件的异步处理和链式操作。对于已经具备RxJava基础的开发者来说,本文将详细介绍如何利用RxJava实现事件总线,并提供了使用建议。 ... [详细]
  • 本文介绍了Java中Currency类的getInstance()方法,该方法用于检索给定货币代码的该货币的实例。文章详细解释了方法的语法、参数、返回值和异常,并提供了一个示例程序来说明该方法的工作原理。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 原文地址:https:www.cnblogs.combaoyipSpringBoot_YML.html1.在springboot中,有两种配置文件,一种 ... [详细]
  • JavaSE笔试题-接口、抽象类、多态等问题解答
    本文解答了JavaSE笔试题中关于接口、抽象类、多态等问题。包括Math类的取整数方法、接口是否可继承、抽象类是否可实现接口、抽象类是否可继承具体类、抽象类中是否可以有静态main方法等问题。同时介绍了面向对象的特征,以及Java中实现多态的机制。 ... [详细]
  • Java String与StringBuffer的区别及其应用场景
    本文主要介绍了Java中String和StringBuffer的区别,String是不可变的,而StringBuffer是可变的。StringBuffer在进行字符串处理时不生成新的对象,内存使用上要优于String类。因此,在需要频繁对字符串进行修改的情况下,使用StringBuffer更加适合。同时,文章还介绍了String和StringBuffer的应用场景。 ... [详细]
  • 本文介绍了Web学习历程记录中关于Tomcat的基本概念和配置。首先解释了Web静态Web资源和动态Web资源的概念,以及C/S架构和B/S架构的区别。然后介绍了常见的Web服务器,包括Weblogic、WebSphere和Tomcat。接着详细讲解了Tomcat的虚拟主机、web应用和虚拟路径映射的概念和配置过程。最后简要介绍了http协议的作用。本文内容详实,适合初学者了解Tomcat的基础知识。 ... [详细]
  • Android源码深入理解JNI技术的概述和应用
    本文介绍了Android源码中的JNI技术,包括概述和应用。JNI是Java Native Interface的缩写,是一种技术,可以实现Java程序调用Native语言写的函数,以及Native程序调用Java层的函数。在Android平台上,JNI充当了连接Java世界和Native世界的桥梁。本文通过分析Android源码中的相关文件和位置,深入探讨了JNI技术在Android开发中的重要性和应用场景。 ... [详细]
  • 本文介绍了Python爬虫技术基础篇面向对象高级编程(中)中的多重继承概念。通过继承,子类可以扩展父类的功能。文章以动物类层次的设计为例,讨论了按照不同分类方式设计类层次的复杂性和多重继承的优势。最后给出了哺乳动物和鸟类的设计示例,以及能跑、能飞、宠物类和非宠物类的增加对类数量的影响。 ... [详细]
  • 本文介绍了在iOS开发中使用UITextField实现字符限制的方法,包括利用代理方法和使用BNTextField-Limit库的实现策略。通过这些方法,开发者可以方便地限制UITextField的字符个数和输入规则。 ... [详细]
  • 本文介绍了在MFC下利用C++和MFC的特性动态创建窗口的方法,包括继承现有的MFC类并加以改造、插入工具栏和状态栏对象的声明等。同时还提到了窗口销毁的处理方法。本文详细介绍了实现方法并给出了相关注意事项。 ... [详细]
  • 本文讨论了微软的STL容器类是否线程安全。根据MSDN的回答,STL容器类包括vector、deque、list、queue、stack、priority_queue、valarray、map、hash_map、multimap、hash_multimap、set、hash_set、multiset、hash_multiset、basic_string和bitset。对于单个对象来说,多个线程同时读取是安全的。但如果一个线程正在写入一个对象,那么所有的读写操作都需要进行同步。 ... [详细]
  • 本文整理了315道Python基础题目及答案,帮助读者检验学习成果。文章介绍了学习Python的途径、Python与其他编程语言的对比、解释型和编译型编程语言的简述、Python解释器的种类和特点、位和字节的关系、以及至少5个PEP8规范。对于想要检验自己学习成果的读者,这些题目将是一个不错的选择。请注意,答案在视频中,本文不提供答案。 ... [详细]
author-avatar
芳方程_269
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有