♥Java8特性知识体系详解♥
Java 8 新特性详解汇总。@pdai
- Java 新特性的增加都是来源于 JSR或者JEP
- JSR论坛: https://jcp.org/en/jsr/detail?id=335
¶ 知识体系
MetaSpace代替Perm Gen
元空间代替了永久代,所以JVM关于永久代的参数也都作废了,取而代之的是关于MetaSpace空间的参数。而且MetaSpace是属于直接内存而不是JVM分配的内存。
为什么要在直接内存里拿出来一块内存作为元空间取代永久代呢?主要的说法有以下几个:
(1)类及方法的信息等比较难确定其大小,因此对于永久代的大小指定比较困难,太小容易出现永久代溢出,太大则容易导致老年代溢出。
(2)永久代会为 GC 带来不必要的复杂度,并且回收效率偏低。
即方便分配管理,因为直接内存空间比较充足;便于回收,因为永久代本来回收垃圾的事件发生概率很低,直接从JVM中拿出可以提高回收效率。
方法区与永久代的关系
很多文章里喜欢把方法区等同与永久代,永久代既然没了,方法区也就没了。但我认为方法区只是一种逻辑上的概念,永久代指物理上的堆内存的一块空间,这块实际的空间完成了方法区存储字节码、静态变量、常量的功能等等。既然如此,现在元空间也可以认为是新的方法区的实现了。
常量池随永久代的变化
几种常量池:
(1)静态常量池:即*.class文件中的常量池,在Class文件结构中,最头的4个字节存储魔数,用于确定一个文件是否能被JVM接受,接着4个字节用于存储版本号,前2个为次版本号,后2个主版本号,再接着是用于存放常量的常量池,由于常量的数量是不固定的,所以常量池的入口放置一个U2类型的数据(constant_pool_count)存储常量池容量计数值。
这种常量池占用class文件绝大部分空间,主要用于存放两大类常量:字面量和符号引用量,字面量相当于Java语言层面常量的概念,如文本字符串、基础数据、声明为final的常值等;符号引用则属于编译原理方面的概念,包括了如下三种类型的常量:类和接口的全限定名、字段名称描述符、方法名称描述符。类的加载过程中的链接部分的解析步骤就是把符号引用替换为直接引用,即把那些描述符(名字)替换为能直接定位到字段、方法的引用或句柄(地址)。
(2)运行时常量池:虚拟机会将各个class文件中的常量池载入到运行时常量池中,即编译期间生成的字面量、符号引用,总之就是装载class文件。为什么它叫运行时常量池呢?因为这个常量池在运行时,里面的常量是可以增加的。如:“+”连接字符生成新字符后调用 intern()方法、生成基础数据的包装类型等等。
(3)字符串常量池 :字符串常量池可以理解为是分担了部分运行时常量池的工作。加载时,对于class文件的静态常量池,如果是字符串就会被装到字符串常量池中。
(4)整型常量池:Integer,类似字符串常量池。管理-128–127的常量。类似的还有Character、Long等常量池(基本数据类型没有,Double、Float也没有常量池)
总结就是:
class文件有常量池存放这个类的信息,占用了大多数空间。但是运行时所有加载进来的class文件的常量池的东西都要放到运行时常量池,这个运行时常量池还可以在运行时添加常量。字符串常量池、Integer等常量池则是分担了运行时常量池的工作,
在永久代移除后,字符串常量池也不再放在永久代了,但是也没有放到新的方法区—元空间里,而是留在了堆里(为了方便回收?)。运行时常量池当然是随着搬家到了元空间里,毕竟它是装类的重要信息的,有它的地方才称得上是方法区。
¶ 函数编程
面向对象编程是对数据进行抽象;函数式编程是对行为进行抽象。
- Lambda 表达式的特点
- Lambda 表达式使用和Stream下的接口
- 函数接口定义和使用,四大内置函数接口Consumer,Function,Supplier, Predicate.
- Comparator排序为例贯穿所有知识点。
详细分析请参看: Java 8 - 函数编程
¶ Optional类
这是一个可以为null的容器对象。如果值存在则isPresent()方法会返回true,调用get()方法会返回该对象。
- Optional类的意义
- Optional类有哪些常用的方法
- Optional举例贯穿所有知识点
- 多重类嵌套Null值判断
详细分析请参看: Java 8 - Optional类
¶ default方法
默认方法给予我们修改接口而不破坏原来的实现类的结构提供了便利,目前java 8的集合框架已经大量使用了默认方法来改进了,当我们最终开始使用Java 8的lambdas表达式时,提供给我们一个平滑的过渡体验。
- 为什么会出现默认方法?
- 接口中出现默认方法,且类可以实现多接口的,那和抽象类有啥区别?
- 多重实现的默认方法冲突怎么办?
详细分析请参看: Java 8 - default方法
¶ 类型注解
那充满争议的类型注解究竟是什么? 复杂还是便捷?
- 注解在JDK哪个版本中出现的,可以在哪些地方用注解?
- 什么是类型注解?
- 类型注解的作用是什么?
- 为什么会出现类型注解(JSR308)?
详细分析请参看: Java 8 - 类型注解
¶ 重复注解
- Java8之前对重复注解是怎么做的?
- Java8对重复注解添加了什么支持?
详细分析请参看: Java 8 - 重复注解
¶ 类型推断
导致类型间互相转换的问题困扰着每个java程序员,通过编译器自动推断类型的东西可以稍微缓解一下类型转换太复杂的问题。
- 什么是泛型?
- Java7对泛型推断做了哪些优化?
- Java8对此有做了哪些优化?
详细分析请参看: Java 8 - 类型推断优化
¶ JRE 精简
模块化特性是javaer所期待的特性, 一个占用资源少的JRE运行环境,紧凑的JRE特性的出现,能带来以后的物联网的发展,甚至还是会有大量的java应用程序出现在物联网上面。
- 为什么精简Java8 JRE,及好处是啥?
- 紧凑的JRE分3种,分别是compact1、compact2、compact3,他们的关系是?
- 在不同平台上如何编译等?
详细分析请参看: Java 8 - JRE精简
¶ LocalDate/LocalDateTime
Date/Calendar槽点, java8对其进行了重写。
- Java8之前的Date有哪些槽点? (Calendar的所有属性都是可变的,SimpleDateFormat的线程不安全性等)
- Java8之前使用哪些常用的第三方时间库?
- Java8关于时间和日期有哪些类和方法,变比Java8之前它的特点是什么?
- 其它语言时间库?
详细分析请参看: Java 8 - LocalDate/LocalDateTime
¶ JavaFX
JavaFX主要致力于富客户端开发,以弥补swing的缺陷,主要提供图形库与media库,支持audio,video,graphics,animation,3D等,同时采用现代化的css方式支持界面设计。同时又采用XUI方式以XML方式设计UI界面,达到显示与逻辑的分离。
- javaFX发展历程?
- Java8对其增加了哪些特性?
详细分析请参看: Java 8 - JavaFX
¶ PermGen移除
PermGen space的全称是Permanent Generation space,是指内存的永久保存区域。PermGen space是Oracle-Sun Hotspot才有,JRockit以及J9是没有这个区域。
- Java8之前 “java.lang.OutOfMemoryError: PermGen space”是怎么引起的,怎么解决的?
- 新增加的元空间(Metaspace)包含哪些东西,画出图
- 元空间(Metaspace)和PermGen对比
详细分析请参看: Java 8 - 移除Permgen
¶ StampedLock
- 为什么会引入StampedLock
- 用Lock写悲观锁和乐观锁举例
- 用StampedLock写悲观锁和乐观锁举例
- 性能对比
详细分析请参看: Java 8 - StampedLock
¶ 其它更新
- Java8 还有哪些其它更新
- 字符串
- Base64
- Random
- Nashorn
- …
详细分析请参看: Java 8 - 其它更新
¶ 参考文档
主要参考自以下文档: