# jdk-version **Repository Path**: fasttime/jdk-version ## Basic Information - **Project Name**: jdk-version - **Description**: 演示jdk各版本新特性 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2020-08-24 - **Last Updated**: 2020-12-20 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README #jdk历史版本 http://www.oracle.com/technetwork/java/javase/archive-139210.html #jdk1.5 ##泛型(Generics) GenericsTest.java ##增强for循环(Enhanced for Loop) https://blog.csdn.net/bleachswh/article/details/53392385 http://shilimin.iteye.com/blog/1632191 for(元素数据类型 变量 : 数组或者Collection集合) {   使用变量即可,该变量就是元素 } ##自动装箱和拆箱(Autoboxing / Unboxing) https://www.cnblogs.com/visionit/p/4160162.html AutoboxingUnboxingTest.java ##枚举(Typesafe Enums) https://blog.csdn.net/fanxiaobin577328725/article/details/53858776 https://www.cnblogs.com/yokoboy/archive/2012/07/25/2608165.html EnumTest.java ##可变长度参数(Varargs) 格式:Object... 注意:可变参数必须是参数列表的最后一个参数。 VarargsTest.java ##静态导入(Static Import) StaticImportTest.java ##注解(Annotations) https://blog.csdn.net/zzamk/article/details/44873231 注解(Annotation)相当于一种标记,在程序中加了注解就等于为程序打上了某种标记,没加,则等于没有某种标记。 以后,javac编译器、开发工具和其他程序可以用反射来了解你的类及各种元素上有无何种标记,看你有什么标记,就去干相应的事。 ##内省(Introspector) http://note.youdao.com/noteshare?id=3b04df7fe2604614b781a8a5a827ee38&sub=37251D8C4BA04D6F99D869E4DC5BD0F1 是 Java语言对Bean类属性、事件的一种缺省处理方法。例如类A中有属性name,那我们可以通过getName,setName来得到其值或者设置新 的值。通过getName/setName来访问name属性,这就是默认的规则。 ##格式化的I/O(Formatter) https://blog.csdn.net/XIAXIA__/article/details/41720485 JDK1.5中,String类新增了一个很有用的静态方法String.format(): format(Locale l, String format, Object... args) 使用指定的语言环境、格式字符串和参数返回一个格式化字符串。 format(String format, Object... args) 使用指定的格式字符串和参数返回一个格式化字符串。 StringFormatTest.java ##线程并发包(java.util.concurrent) https://blog.csdn.net/youyou1543724847/article/details/52735510 原子类,atomic子包,其中有几个以Atomic打头的类,例如AtomicInteger和AtomicLong。它们利用了现代处理器的特性,可以用非阻塞的方式完成原子操作。 锁相关,java.util.concurrent.locks包下常用的类和接口,例如ReadWriteLock,ReentrantReadWriteLock 线程同步工具,Semaphore,CountDownLatch,CyclicBarrier 线程安全集合,例如ConcurrentHashMap 线程池 ##CMS垃圾收集器 CMS,全称Concurrent Low Pause Collector,是jdk1.4后期版本开始引入的新gc算法,在jdk5和jdk6中得到了进一步改进 ##JConsole工具 #jdk1.6 http://developer.51cto.com/art/200907/134481.htm ##Desktop类和SystemTray类 前者可以用来打开系统默认浏览器浏览指定的URL,打开系统默认邮件客户端给指定的邮箱发邮件,用默认应用程序打开或编辑文件(比如,用记事本打开以txt为后缀名的文件), 用系统默认的打印机打印文档;后者可以用来在系统托盘区创建一个托盘程序。 ##使用JAXB2来实现对象与XML之间的映射 JAXB是Java Architecture for XML Binding的缩写,可以将一个Java对象转变成为XML格式,反之亦然。 我们把对象与关系数据库之间的映射称为ORM,其实也可以把对象与XML之间的映射称为OXM(Object XML Mapping)。原来JAXB是Java EE的一部分,在JDK1.6中, SUN将其放到了Java SE中,这也是SUN的一贯做法。JDK1.6中自带的这个JAXB版本是2.0,比起1.0(JSR 31)来,JAXB2(JSR 222)用JDK5的新特性Annotation来标识要作绑定的类和属性等, 这就极大简化了开发的工作量。实际上,在Java EE 5.0中,EJB和Web Services也通过Annotation来简化开发工作。另外,JAXB2在底层是用StAX(JSR 173)来处理XML文档。 除了JAXB之外,我们还可以通过XMLBeans和Castor等来实现同样的功能。 ##理解StAX StAX(JSR 173)是JDK1.6.0中除了DOM和SAX之外的又一种处理XML文档的API。 StAX 的来历:在JAXP1.3(JSR 206)有两种处理XML文档的方法:DOM(Document Object Model)和SAX(Simple API for XML)。 由于JDK1.6.0中的JAXB2(JSR 222)和JAX-WS 2.0(JSR 224)都会用到StAX所以Sun决定把StAX加入到JAXP家族当中来,并将JAXP的版本升级到1.4(JAXP1.4是JAXP1.3的维护版本)。JDK1.6里面JAXP的版本就是1.4。 StAX是The Streaming API for XML的缩写,一种利用拉模式解析(pull-parsing)XML文档的API.StAX通过提供一种基于事件迭代器(Iterator)的API让程序员去控制xml文档解析过程 ,程序遍历这个事件迭代器去处理每一个解析事件,解析事件可以看做是程序拉出来的,也就是程序促使解析器产生一个解析事件然后处理该事件,之后又促使解析器产生下一个解析事件,如此循环直到碰到文档结束符; SAX也是基于事件处理xml文档,但却是用推模式解析,解析器解析完整个xml文档后,才产生解析事件,然后推给程序去处理这些事件;DOM采用的方式是将整个xml文档映射到一颗内存树, 这样就可以很容易地得到父节点和子结点以及兄弟节点的数据,但如果文档很大,将会严重影响性能。 ##JAX-WS https://blog.csdn.net/wjlbqi/article/details/43453347 JDK1.6中自带了webservice的功能,因为集成了JAX-WS,这非常方便,不用再用第三方包来开发了。 ##Compiler API 现在我 们可以用JDK1.6 的Compiler API(JSR 199)去动态编译Java源文件,Compiler API结合反射功能就可以实现动态的产生Java代码并编译执行这些代码,有点动态语言的特征。 这个特性对于某些需要用到动态编译的应用程序相当有用,比如JSP Web Server,当我们手动修改JSP后,是不希望需要重启Web Server才可以看到效果的,这时候我们就可以用Compiler API来实现动态编译JSP文件, 当然,现在的JSP Web Server也是支持JSP热部署的,现在的JSP Web Server通过在运行期间通过Runtime.exec或ProcessBuilder来调用javac来编译代码,这种方式需要我们产生另一个进程去做编译工作, 不够优雅而且容易使代码依赖与特定的操作系统;Compiler API通过一套易用的标准的API提供了更加丰富的方式去做动态编译,而且是跨平台的。 ##轻量级Http Server API http://blog.163.com/web_promise/blog/static/1096316552011224101531794/ JDK1.6 提供了一个简单的Http Server API,据此我们可以构建自己的嵌入式Http Server,它支持Http和Https协议,提供了HTTP1.1的部分实现,没有被实现的那部分可以通过扩展已有的Http Server API来实现, 程序员必须自己实现HttpHandler接口,HttpServer会调用HttpHandler实现类的回调方法来处理客户端请求,在这里,我们把一个Http请求和它的响应称为一个交换,包装成HttpExchange类,HttpServer负责将HttpExchange传给HttpHandler实现类的回调方法。 ##插入式注解处理API(Pluggable Annotation Processing API) https://blog.csdn.net/yczz/article/details/34116189 https://blog.csdn.net/u013855332/article/details/51990520 插入式注解处理API(JSR 269)提供一套标准API来处理Annotations,在编译期间而不是运行期间处理Annotation, Annotation Processor相当于编译器的一个插件,所以称为插入式注解处理. JSR 269主要被设计成为针对Tools或者容器的API. 举个例子,我们想建立一套基于Annotation的单元测试框架(如TestNG),在测试类里面用Annotation来标识测试期间需要执行的测试方法。 lombok使用了该技术 ##JDBC4.0 ##用Console开发控制台程序 JDK1.6中提供了java.io.Console 类专用来访问基于字符的控制台设备。你的程序如果要与Windows下的cmd或者Linux下的Terminal交互,就可以用Console类代劳。但我们不总是能得到可用的Console,一个JVM是否有可用的Console依赖于底层平台和JVM如何被调用。 如果JVM是在交互式命令行(比如Windows的cmd)中启动的,并且输入输出没有重定向到另外的地方,那么就可以得到一个可用的Console实例。 ##JDK1.6中对脚本语言的支持 https://blog.csdn.net/qq78827534/article/details/80246961 JDK1.6加入了对Script(JSR223)的支持。这是一个脚本框架,提供了让脚本语言来访问Java内部的方法。你可以在运行的时候找到脚本引擎,然后调用这个引擎去执行脚本。这个脚本API允许你为脚本语言提供Java支持。另外,Web Scripting Framework允许脚本代码在任何的Servlet容器(例如Tomcat)中生成Web内容。 ##Common Annotations https://blog.csdn.net/chinajash/article/details/1479964 Common annotations原本是Java EE 5.0(JSR 244)规范的一部分,现在SUN把它的一部分放到了Java SE 6.0中 例如PostConstruct,PreDestroy ##JVisualVM工具 #jdk1.7 ##泛型实例化类型自动推断(Diamond Operator) Map> trades = new TreeMap> (); Map> trades = new TreeMap <> (); ##switch语句支持字符串变量 WithSwitchStatementTest.java ##try-with-resources语句 try-with-resources语句是一个声明一个或多个资源的try语句。一个资源作为一个对象,必须在程序结束之后关闭。try-with-resources语句确保在语句的最后每个资源都被关闭,任何实现了Java.lang.AutoCloseable和java.io.Closeable的对象都可以使用try-with-resource来实现异常处理和关闭资源。 TryWithResourcesTest.java ## 新的整数字面表达方式 - "0b"前缀和"_"连数符 a. 表示二进制字面值的前缀0b。 比如以下三个变量的值相同: byte b1 = 0b00100001; // 二进制 byte b2 = 0x21; // 16进制 byte b3 = 33; // 10进制 b. 字面常量数字的下划线。用下划线连接整数提升其可读性,自身无含义,不可用在数字的起始和末尾。 Java编码语言对给数值型的字面值加下划线有严格的规定。如上所述,你只能在数字之间用下划线。你不能用把一个数字用下划线开头,或者已下划线结尾。 ##在单个catch代码块中捕获多个异常 https://www.jianshu.com/p/0d4a958b0f52 如果用一个catch块处理多个异常,可以用管道符(|)将它们分开,在这种情况下异常参数变量(ex)是定义为final的,所以不能被修改。这一特性将生成更少的字节码并减少代码冗余。 catch(ExceptionOne | ExceptionTwo | ExceptionThree e) { } ##编译器对重新抛出异常(rethrown exceptions)的处理 https://www.jianshu.com/p/0d4a958b0f52 RethrowExceptionTest.java ##NIO2.0 http://elf8848.iteye.com/blog/1751384 JDK1.7升级了NIO类库,升级后的NIO类库被称为NIO2.0,引人注目的是,Java正式提供了异步文件I/O操作,同时提供了与UNIX网络编程事件驱动I/O对应的AIO。 ##JDK7文件处理,监听文件系统的更改 https://blog.csdn.net/hpb21/article/details/51286465 http://janeky.iteye.com/blog/1049328 java.nio.file包下,实用的工具类,Path,Paths,Files,FileSystem, WatchService ##JDK7中的Fork/Join框架 https://blog.csdn.net/zdy0_2004/article/details/50513482 轻松实现多核时代的并行计算 ##Java语言的动态性-InvokeDynamic https://www.cnblogs.com/wade-luffy/p/6058087.html java.lang.invoke包 Java虚拟机的字节码指令集的数量从Sun公司的第一款Java虚拟机问世至JDK 7来临之前的十余年时间里,一直没有发生任何变化。随着JDK 7的发布,字节码指令集终于迎来了第一位新成员——invokedynamic指令。这条新增加的指令是JDK 7实现“动态类型语言”(Dynamically Typed Language)支持而进行的改进之一,也是为JDK 8可以顺利实现Lambda表达式做技术准备。 ##在可变参数方法中传递非具体化参数(Non-Relfiable Formal Parameters),改进编译警告和错误 http://www.365mini.com/page/13.htm HeapPollutionTest.java ##SafeArgs https://blog.csdn.net/tianshangyu333/article/details/50001319 ##JDK7的新特性JDBC4.1 https://www.aliyun.com/jiaocheng/338036.html ##JDK1.7的G1收集器 http://f.dataguru.cn/thread-514678-1-1.html ##新增工具类Objects 新增类 java.util.Objects (JDK对工具类的命名一向是以s结尾,例如Collections, Arrays) ##新增Java Mission Control工具 #jdk1.8 ##函数式接口 @FunctionalInterface ##Lambda 表达式 https://gitee.com/zhangli002/functional-reactive-programming ##Stream API https://gitee.com/zhangli002/functional-reactive-programming ##方法引用 方法引用提供了非常有用的语法,可以直接引用已有Java类或对象(实例)的方法或构造器。与lambda联合使用,方法引用可以使语言的构造更紧凑简洁,减少冗余代码。 ##接口默认方法 默认方法就是一个在接口里面有了一个实现的方法 ##接口静态方法 接口里可以声明静态方法,并且可以实现。 ##为 java.lang.Iterable 接口增加了 forEach() 方法 ##Optional 类 Optional 类已经成为 Java 8 类库的一部分,用来解决空指针异常。 ##Date Time API − 加强对日期与时间的处理 http://blog.csdn.net/sun_promise/article/details/51383618 jdk1.8之前的java.util.Date和Calendar超级难用,所以java开发人员一般都用joda-time, 因为joda-time已经成为事实上的标准。 jdk1.8在充分参考了joda-time的实现的基础上,重新设计了java.time API, 自此joda-time项目建义开发人员转到java.time的API上。 ##Nashorn:新的JavaScript 引擎 Java 8提供了一个新的Nashorn javascript引擎,它允许我们在JVM上运行特定的javascript应用。 从JDK 1.8开始,Nashorn取代Rhino(JDK 1.6, JDK1.7)成为Java的嵌入式JavaScript引擎。Nashorn完全支持ECMAScript 5.1规范以及一些扩展。它使用基于JSR 292的新语言特性,其中包含在JDK 7中引入的 invokedynamic,将JavaScript编译成Java字节码。 与先前的Rhino实现相比,这带来了2到10倍的性能提升。 jjs是个基于Nashorn引擎的命令行工具。它接受一些JavaScript源代码为参数,并且执行这些源代码。 ##Java8 Base64 http://www.runoob.com/java/java8-base64.html 在Java 8中,Base64编码已经成为Java类库的标准。 Java 8 内置了 Base64 编码的编码器和解码器。 ##Java8类依赖分析器:jdeps https://blog.csdn.net/tieselingzhi/article/details/52815912 jdeps是一个相当棒的命令行工具,它可以展示包层级和类层级的Java类依赖关系,它以.class文件、目录或者Jar文件为输入,然后会把依赖关系输出到控制台。 ##Java8重复注解@Repeatble https://blog.csdn.net/TimHeath/article/details/71374718 ##Java8新增的类型注解 https://blog.csdn.net/u014207606/article/details/52302731 Java8为ElementType枚举增加了TYPE_PARAMETER、TYPE_USE两个枚举值,从而可以使用@Target(ElementType_TYPE_USE)修饰注解定义,这种注解被称为类型注解,可以用在任何使用到类型的地方。 ##HashMap性能优化 从结构实现来讲,HashMap是数组+链表+红黑树(JDK1.8增加了红黑树部分)实现的 ##Arrays.parallelSort Java8之前,Arrays.sort来对原生数组进行排序,这个API会使用归并排序或者Tim排序来进行排序. Java8出来之后,有一个新API用来进行排序,这就是Arrays.ParallelSort,这是一种并行排序,让我们来看看它是怎么实现的。 Arrays.ParallelSort使用了Java7的Fork/Join框架使排序任务可以在现场池中的多个线程中进行,Fork/Join实现了一种任务窃取算法,一个闲置的线程可以窃取其他线程的闲置任务进行处理。 ##JDBC4.2 ##编译器优化 Java 8将方法的参数名加入了字节码中,这样在运行时通过反射就能获取到参数名,只需要在编译时使用-parameters参数。 ##元空间替换持久代 #jdk1.9 ##modularity System 模块系统 Java 9中主要的变化是已经实现的模块化系统。 Modularity提供了类似于OSGI框架的功能,模块之间存在相互的依赖关系,可以导出一个公共的API,并且隐藏实现的细节,Java提供该功能的主要的动机在于, 减少内存的开销,在JVM启动的时候,至少会有30~60MB的内存加载,主要原因是JVM需要加载rt.jar,不管其中的类是否被classloader加载,第一步整个jar都会被JVM加载到内存当中去,模块化可以根据模块的需要加载程序运行需要的class。 在引入了模块系统之后,JDK 被重新组织成 94 个模块。Java 应用可以通过新增的 jlink 工具,创建出只包含所依赖的 JDK 模块的自定义运行时镜像。 这样可以极大的减少 Java 运行时环境的大小。使得JDK可以在更小的设备中使用。采用模块化系统的应用程序只需要这些应用程序所需的那部分JDK模块,而非是整个JDK框架了。 ##HTTP/2 JDK9之前提供HttpURLConnection API来实现Http访问功能,但是这个类基本很少使用,一般都会选择Apache的Http Client,此次在Java 9的版本中引入了一个新的package:java.net.http,里面提供了对Http访问很好的支持,不仅支持Http1.1而且还支持HTTP2(什么是HTTP2?请参见HTTP2的时代来了...),以及WebSocket,据说性能特别好。 ##JShell 用过Python的童鞋都知道,Python 中的读取-求值-打印循环( Read-Evaluation-Print Loop )很方便。它的目的在于以即时结果和反馈的形式。 java9引入了jshell这个交互性工具,让Java也可以像脚本语言一样来运行,可以从控制台启动 jshell ,在 jshell 中直接输入表达式并查看其执行结果。当需要测试一个方法的运行效果,或是快速的对表达式进行求值时,jshell 都非常实用。 除了表达式之外,还可以创建 Java 类和方法。jshell 也有基本的代码完成功能。我们在教人们如何编写 Java 的过程中,不再需要解释 “public static void main(String [] args)” 这句废话。 ##不可变集合工厂方法 Java 9增加了List.of()、Set.of()、Map.of()和Map.ofEntries()等工厂方法来创建不可变集合。 List strs = List.of("Hello", "World"); List strs List.of(1, 2, 3); Set strs = Set.of("Hello", "World"); Set ints = Set.of(1, 2, 3); Map maps = Map.of("Hello", 1, "World", 2); 除了更短和更好阅读之外,这些方法也可以避免您选择特定的集合实现。在创建后,继续添加元素到这些集合会导致 “UnsupportedOperationException” 。 ##私有接口方法 Java 8 为我们提供了接口的默认方法和静态方法,接口也可以包含行为,而不仅仅是方法定义。 默认方法和静态方法可以共享接口中的私有方法,因此避免了代码冗余,这也使代码更加清晰。如果私有方法是静态的,那这个方法就属于这个接口的。并且没有静态的私有方法只能被在接口中的实例调用。 ##HTML5风格的Java帮助文档 Java 8之前的版本生成的Java帮助文档是在HTML 4中。在Java 9中,Javadoc 的输出现在符合兼容 HTML5 标准。现在HTML 4是默认的输出标记语言,但是在之后发布的JDK中,HTML 5将会是默认的输出标记语言。 ##多版本兼容 JAR http://openjdk.java.net/jeps/238 多版本兼容 JAR 功能能让你创建仅在特定版本的 Java 环境中运行库程序时选择使用的 class 版本 ##统一JVM 日志 https://www.cnblogs.com/IcanFixIt/p/7259712.html Java 9中 ,JVM 有了统一的日志记录系统,可以使用新的命令行选项-Xlog 来控制 JVM 上 所有组件的日志记录。该日志记录系统可以设置输出的日志消息的标签、级别、修饰符和输出目标等。 ##java9的垃圾收集机制 1.Java9移除了在Java8中被废弃的垃圾回收器配置组合: DefNew + CMS ParNew + SerialOld Incremental CMS 2.把G1设为默认的垃圾回收器实现,替代了java7,8默认使用的Parallel GC ##响应式流 JDK9中的Flow API对应响应式流规范,响应式流规范是一种事实标准。JEP 266包含了一组最小接口集合,这组接口能捕获核心的异步发布与订阅。希望在未来第三方能够实现这些接口,并且能共享其方式。 ##Try-With-Resources改进 http://www.importnew.com/21544.html 在Java 7中,try-with-resouces语法要求为每一个资源声明一个新的变量,而且这些资源由try-with-resources语句进行管理。 在就Java 9中,有另外一个改进:如果一个资源被final或者等效于final变量引用,则在不需要声明一个新的变量的情况下,try-with-resources就可以管理这个资源。 ##钻石(diamond)操作符范围的延伸 https://yq.aliyun.com/articles/79219 DiamondTest.java ##增强的弃用注解@Deprecated https://www.cnblogs.com/IcanFixIt/p/7234054.html?utm_source=debugrun&utm_medium=referral 注释@Deprecated可以标记Java API。注释@Deprecated有很多种含义,例如它可以表示在不远的将来的某个时间,被标记的API将会被移除。它也可以表示这个API已经被破坏了,并不应该再被使用。它还有其它很多含义。为了提供更多有关@Deprecated的信息,@Deprecated添加了forRemoval元素和since元素。 Java SE 9 中也提供了扫描jar文件的工具jdeprscan。这款工具也可以扫描一个聚合类,这个类使用了Java SE中的已废弃的API元素。 这个工具将会对使用已经编译好的库的应用程序有帮助,这样使用者就不知道这个已经编译好的库中使用了那些已废弃的API。 ##注释SafeVarargs范围的延伸 直到Java 8,@SafeVarargs只能在静态方法、final方法和构造器上使用。这些方法或者构造器是不能被覆盖的。这些方法中缺少另一个不能被覆盖的方法,这个方法就是私有方法。Java 9可以将@SafeVarargs添加到私有方法上。下面的例子在Java 9中是正确的,但是在Java 8中就会抛出编译时错误:注释@SafeVarargs不能在非final的实例方法iAmSafeVaragrsMethod上使用。 @SafeVarargs private void iAmSafeVaragrsMethod(String... varagrgs){     for (String each: varagrgs) {       System.out.println(each);     } } ##废弃Applet API,废弃Java浏览器插件 ##保留下划线字符。变量不能被命名为_; #jdk1.10 ##局部变量类型推断Local-Variable Type Inference(重磅) LocalVariableTest.java ##G1垃圾收集器并行化(Parallel Full GC for G1) 随着JDK 9的发布,Garbage-First(G1)GC取代了Parallel Collector作为默认GC。为了减少JDK 9之外的JDK版本中垃圾收集的影响,G1收集器将被并行化(以匹配并行收集器的特征)。虽然目前还没有关于这个并行化的实现细节的信息,但是可以在JEP 307规范中找到关于此更改的更多细节。