单类中初始化顺序
在单个类中,对于静态变量、静态初始化块、变量、初始化块、构造器,它们的初始化顺序以此是:
(静态变量、静态初始化块)>(变量、初始化块)>构造器。1 | 0.303: [Full GC (System.gc()) [PSYoungGen: 464K->0K(76288K)] [ParOldGen: 8K->428K(175104K)] 472K->428K(251392K), |
0.303:表示 GC发生的时间,从java虚拟机启动以来经过的秒数。
[Full GC (System.gc()) :表示 垃圾收集的停顿类型。有 [GC
, [Full
, [Full GC(System.gc())
类型。 其中,有 [Full 说明GC过程中发生了STW。如果调用了System.gc()方法触发了收集,则显示:[Full GC(System.gc())
[DefNew
、[Tenured
、[Perm
等类型。 此处显示的区域名称与使用GC的垃圾收集器有关。Serial收集器中的新生代名为“Default New Generation”,所以显示的是“[DefNew”,如果是ParNew收集器,新生代名称就会变为“[ParNew”,意为“Parallel New Generation”。如果采用Parallel Scavenge收集器,那它配套的新生代称为“PSYoungGen”,老年代和永久代同理,名称也是由收集器决定的。
自动装箱机制:在将int
类型的数据直接赋值给Integer
类型时,会触发自动装箱机制,自动装箱机制的实质是:调用了Integer.valueOf(i)
方法(通过跟踪debug可知),阅读源码1
2
3
4
5public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
可知,使用了Integer中的静态内部类IntegerCache
类,其实现为:
1 |
|
可知,该静态内部类缓存了从-128到127这256个最常用数的Integer对象,Integer类被加载的时候这些缓存对象就初始化好了。因此可知在-128到127这256个最常用数在发生自动装箱的时候,它们的地址是相同的。
因此:
1 | Integer a1 = new Integer(1); |
关于java虚拟机的学习,网上有许多学习文章。同时周志明老师编写的图书:《深入理解JVM虚拟机》也是JVM学习者必读图书之一。虽说之前也有相关的学习过,但是一直没有进行梳理,导致知识相对很零散,所以为了日后方便自己或他人学习,本文将对JVM进行简略的知识梳理。
Java内存模型,往往是指Java程序在运行时内存的模型,而Java代码是运行在Java虚拟机之上的,由Java虚拟机通过解释执行(解释器)或编译执行(即时编译器)来完成,故Java内存模型,也就是指Java虚拟机的运行时内存模型。
JVM运行时数据区,包括5部分:堆,方法区,程序计数器,虚拟机栈,本地方法栈。在这5部分中,其中:堆,方法区是共享数据区,即所有线程共享的内存区域;程序计数器,虚拟机栈,本地方法栈是线程私有,即每个线程都会有自己的独立内存区域,各线程之间互不影响,独立存储
。
Java为数据结构中的映射定义了一个接口java.util.Map,此接口主要有四个常用的实现类,分别是HashMap、Hashtable、LinkedHashMap和TreeMap。其中HashMap是Java程序员使用频率最高的用于映射(键值对)处理的数据类型。HashMap是一种无序的,且允许null作为键值对的Map集合。该类除了不是同步的,且允许null键值对外,其他都与Hashtable基本一致。由于Hashtable是遗留类,且并发性不如ConcurrentHashMap,所以在新代码中基本上不使用。HashMap的底层采用 Node数组+链表+红黑树
的存储结构。该类除了没有并发功能外,与 ConcurrentHashMap 类基本一致。
关于 java 的集合框架,我们前面已经学习了 Collection接口
及其子类,比如:ArrayList, LinkedList, HashSet 等。在本篇中,我们将学习日常编程中最常用的另一集合分支:Map。我们最常用的Map集合为HashMap,从类图中,我们可知,它的父类为AbstractMap
,所以,我们从AbstractMap
入手分析Map的相关源码。
在前面几个章节中,已经对集合中的 List
列表一支进行了相关的学习。在我们日常编程中,使用最多的集合还有 Set
。本章我们将学习Set的相关知识。
1 | graph TD |
在上图中,我们可以看到,Collection接口
的另一分支:Set
集合,常用的有:HashSet,TreeSet等。在此,我们先学习一下平时最常用的 HashSet。
在上篇文章 ArrayList源码学习 中,我们队 ArrayList 的源码进行了相应的分析。在学习的过程中,我们已经知道,ArrayList的底层是数组结构
。所有操作都是针对数组进行的。在本篇中,我们学习一下List接口的另一个重要的子类LinkedList。最后在总结一下二者的区别。
1 | //LinkedList是双链表结构,继承了List和Deque接口 |
从LinkedList的源码中,我们可以发现:LinkedList 不仅继承了List接口,而且还继承了Deque,即:Queue的子类。因此可知,LinkedList不仅可以当做列表使用,而且还能实现队列的功能。
与ArrayList底层数组结构
不同的是,LinkedList的底层数据结构是链接
,即由节点构成。底层数据结构的差异自然而然就会导致对存储对象的操作差异。