Java核心知识点整理大全4-笔记

             

目录

                2.9.1.5. 符号引用

                2.9.1.6. 直接引用

                2.9.1.7. 初始化

                2.9.1.8. 类构造器

                2.9.2. 类加载器

                        2.9.2.1. 启动类加载器(Bootstrap ClassLoader)

                        2.9.2.2. 扩展类加载器(Extension ClassLoader)

                         2.9.2.3. 应用程序类加载器(Application ClassLoader):

                        2.9.3. 双亲委派

                        2.9.4. OSGI(动态模型系统)

                        2.9.4.1. 动态改变构造

                        2.9.4.2. 模块化编程与热插拔

               3.1接口继承关系和实现

                3.2.List

                        3.2.1. ArrayList(数组)

                        3.2.2. Vector(数组实现、线程同步)

                         3.2.3. LinkList(链表)

                3.3.Set

                        3.3.1.2. TreeSet(二叉树)

                        3.3.1.3. LinkHashSet(HashSet+LinkedHashMap)


Java核心知识点整理大全4-笔记_第1张图片

   2.9.1.5. 符号引用

         符号引用与虚拟机实现的布局无关,引用的目标并不一定要已经加载到内存中。各种虚拟 机实现的内存布局可以各不相同,但是它们能接受的符号引用必须是一致的,因为符号引 用的字面量形式明确定义在 Java 虚拟机规范的 Class 文件格式中。

                2.9.1.6. 直接引用

         直接引用可以是指向目标的指针,相对偏移量或是一个能间接定位到目标的句柄。如果有 了直接引用,那引用的目标必定已经在内存中存在。

                2.9.1.7. 初始化

        初始化阶段是类加载最后一个阶段,前面的类加载阶段之后,除了在加载阶段可以自定义类加载 器以外,其它操作都由 JVM 主导。到了初始阶段,才开始真正执行类中定义的 Java 程序代码。

                2.9.1.8. 类构造器

         初始化阶段是执行类构造器方法的过程。方法是由编译器自动收集类中的类变 量的赋值操作和静态语句块中的语句合并而成的。虚拟机会保证子方法执行之前,父类 的方法已经执行完毕,如果一个类中没有对静态变量赋值也没有静态语句块,那么编译 器可以不为这个类生成()方法。

                注意以下几种情况不会执行类初始化:

        1. 通过子类引用父类的静态字段,只会触发父类的初始化,而不会触发子类的初始化。

        2. 定义对象数组,不会触发该类的初始化。

        3. 常量在编译期间会存入调用类的常量池中,本质上并没有直接引用定义常量的类,不会触 发定义常量所在的类。

        4. 通过类名获取 Class 对象,不会触发类的初始化。

        5. 通过 Class.forName 加载指定类时,如果指定参数 initialize 为 false 时,也不会触发类初 始化,其实这个参数是告诉虚拟机,是否要对类进行初始化。

        6. 通过 ClassLoader 默认的 loadClass 方法,也不会触发初始化动作。

                2.9.2. 类加载器

        虚拟机设计团队把加载动作放到 JVM 外部实现,以便让应用程序决定如何获取所需的类,JVM 提 供了 3 种类加载器:

                        2.9.2.1. 启动类加载器(Bootstrap ClassLoader)

        1. 负责加载 JAVA_HOME\lib 目录中的,或通过-Xbootclasspath 参数指定路径中的,且被 虚拟机认可(按文件名识别,如 rt.jar)的类。

                        2.9.2.2. 扩展类加载器(Extension ClassLoader)

        2. 负责加载 JAVA_HOME\lib\ext 目录中的,或通过 java.ext.dirs 系统变量指定路径中的类 库。

                         2.9.2.3. 应用程序类加载器(Application ClassLoader):

        3. 负责加载用户路径(classpath)上的类库。 JVM 通过双亲委派模型进行类的加载,当然我们也可以通过继承 java.lang.ClassLoader 实现自定义的类加载器。

Java核心知识点整理大全4-笔记_第2张图片

                        2.9.3. 双亲委派

                当一个类收到了类加载请求,他首先不会尝试自己去加载这个类,而是把这个请求委派给父 类去完成,每一个层次类加载器都是如此,因此所有的加载请求都应该传送到启动类加载其中, 只有当父类加载器反馈自己无法完成这个请求的时候(在它的加载路径下没有找到所需加载的 Class),子类加载器才会尝试自己去加载。

        采用双亲委派的一个好处是比如加载位于 rt.jar 包中的类 java.lang.Object,不管是哪个加载 器加载这个类,最终都是委托给顶层的启动类加载器进行加载,这样就保证了使用不同的类加载 器最终得到的都是同样一个 Object 对象。 

Java核心知识点整理大全4-笔记_第3张图片

                        2.9.4. OSGI(动态模型系统)

                 OSGi(Open Service Gateway Initiative),是面向 Java 的动态模型系统,是 Java 动态化模块化系 统的一系列规范。

                        2.9.4.1. 动态改变构造

                 OSGi 服务平台提供在多种网络设备上无需重启的动态改变构造的功能。为了最小化耦合度和促使 这些耦合度可管理,OSGi 技术提供一种面向服务的架构,它能使这些组件动态地发现对方。

                        2.9.4.2. 模块化编程与热插拔

                OSGi 旨在为实现 Java 程序的模块化编程提供基础条件,基于 OSGi 的程序很可能可以实现模块级 的热插拔功能,当程序升级更新时,可以只停用、重新安装然后启动程序的其中一部分,这对企 业级程序开发来说是非常具有诱惑力的特性。

                 OSGi 描绘了一个很美好的模块化开发目标,而且定义了实现这个目标的所需要服务与架构,同时 也有成熟的框架进行实现支持。但并非所有的应用都适合采用 OSGi 作为基础架构,它在提供强大 功能同时,也引入了额外的复杂度,因为它不遵守了类加载的双亲委托模型.

3:Java集合

               3.1接口继承关系和实现

                集合类存放于 Java.util 包中,主要有 3 种:set(集)、list(列表包含 Queue)和 map(映射)。

        1. Collection:Collection 是集合 List、Set、Queue 的最基本的接口。

         2. Iterator:迭代器,可以通过迭代器遍历集合中的数据

        3. Map:是映射表的基础接口

                3.2.List

        Java 的 List 是非常常用的数据类型。List 是有序的 Collection。Java List 一共三个实现类: 分别是 ArrayList、Vector 和 LinkedList。

                        3.2.1. ArrayList(数组)

                 ArrayList 是最常用的 List 实现类,内部是通过数组实现的,它允许对元素进行快速随机访问。数 组的缺点是每个元素之间不能有间隔,当数组大小不满足时需要增加存储能力,就要将已经有数 组的数据复制到新的存储空间中。当从 ArrayList 的中间位置插入或者删除元素时,需要对数组进 行复制、移动、代价比较高。因此,它适合随机查找和遍历,不适合插入和删除。

                        3.2.2. Vector(数组实现、线程同步)

                 Vector 与 ArrayList 一样,也是通过数组实现的,不同的是它支持线程的同步,即某一时刻只有一 个线程能够写 Vector,避免多线程同时写而引起的不一致性,但实现同步需要很高的花费,因此, 访问它比访问 ArrayList 慢。

                         3.2.3. LinkList(链表)

                 LinkedList 是用链表结构存储数据的,很适合数据的动态插入和删除,随机访问和遍历速度比较 慢。另外,他还提供了 List 接口中没有定义的方法,专门用于操作表头和表尾元素,可以当作堆 栈、队列和双向队列使用。

Java核心知识点整理大全4-笔记_第4张图片

                3.3.Set

                Set 注重独一无二的性质,该体系集合用于存储无序(存入和取出的顺序不一定相同)元素,值不能重 复。对象的相等性本质是对象 hashCode 值(java 是依据对象的内存地址计算出的此序号)判断 的,如果想要让两个不同的对象视为相等的,就必须覆盖 Object 的 hashCode 方法和 equals 方 法。

                哈希表边存放的是哈希值。HashSet 存储元素的顺序并不是按照存入时的顺序(和 List 显然不 同) 而是按照哈希值来存的所以取数据也是按照哈希值取得。元素的哈希值是通过元素的 hashcode 方法来获取的, HashSet 首先判断两个元素的哈希值,如果哈希值一样,接着会比较 equals 方法 如果 equls 结果为 true ,HashSet 就视为同一个元素。

                如果 equals 为 false 就不是 同一个元素。 哈希值相同 equals 为 false 的元素是怎么存储呢,就是在同样的哈希值下顺延(可以认为哈希值相 同的元素放在一个哈希桶中)。也就是哈希一样的存一列。如图 1 表示 hashCode 值不相同的情 况;图 2 表示 hashCode 值相同,但 equals 不相同的情况。

Java核心知识点整理大全4-笔记_第5张图片

HashSet 通过 hashCode 值来确定元素在内存中的位置。一个 hashCode 位置上可以存放多个元 素。

                        3.3.1.2. TreeSet(二叉树)

        1. TreeSet()是使用二叉树的原理对新 add()的对象按照指定的顺序排序(升序、降序),每增 加一个对象都会进行排序,将对象插入的二叉树指定的位置。

         2. Integer 和 String 对象都可以进行默认的 TreeSet 排序,而自定义类的对象是不可以的,自 己定义的类必须实现 Comparable 接口,并且覆写相应的 compareTo()函数,才可以正常使 用。

        3. 在覆写 compare()函数时,要返回相应的值才能使 TreeSet 按照一定的规则来排序

         4. 比较此对象与指定对象的顺序。如果该对象小于、等于或大于指定对象,则分别返回负整 数、零或正整数。

                        3.3.1.3. LinkHashSet(HashSet+LinkedHashMap)

                对于 LinkedHashSet 而言,它继承与 HashSet、又基于 LinkedHashMap 来实现的。 LinkedHashSet 底层使用 LinkedHashMap 来保存所有元素,它继承与 HashSet,其所有的方法 操作上又与 HashSet 相同,因此 LinkedHashSet 的实现上非常简单,只提供了四个构造方法,并 通过传递一个标识参数,调用父类的构造器,底层构造一个 LinkedHashMap 来实现,在相关操 作上与父类 HashSet 的操作相同,直接调用父类 HashSet 的方法即可

        Java核心知识点整理大全4-笔记_第6张图片

你可能感兴趣的:(Java,笔记,jvm)