Java 8新特性前瞻

时间:2022-09-22 21:53:44

快端午小长假了,要上线的项目差不多完结了,终于有时间可以坐下来写篇博客了。

这是篇对我看到的java 8新特性的一些总结,也是自己学习过程的总结。

几乎可以说java 8是目前为止,自2004年java 5发布以来的java世界中最大的事件了。它带来了java语言层面上的诸多改变,主要包括下面一些方面:语法、编译器、库、工具和运行时。

一,语法层面:

1,Lambda表达式。

lambda表达式是一种可调用对象,它允许我们将函数作为函数参数传入。诸如C++、Groovy、Scala都已经支持lambda表达式。lambda表达式的设计已经花费了许多时间和社区努力,它已经有了比较简洁和紧凑的结构。它最简单的形式如下:

 Arrays.asList( "a", "b", "d" ).forEach( e -> System.out.println( e ) );

在这段代码里面,它只包含了变量e和函数体以及箭头运算符。e是ArrayList里面的String类型参数,被编译器调用,通过forEach循环来获取,并通过—>来调用函数体,将变量e打印出来。该段代码的lambda完整格式如下:

 Arrays.asList( "a", "b", "d" ).forEach( e -> {
System.out.print( e );
System.out.print( e );
} );

同时,lambda表达式也可以引用其它变量,但是该变量应该显式地声明为final,如下:

 final String separator = ",";
Arrays.asList( "a", "b", "d" ).forEach(
( String e ) -> System.out.print( e + separator ) );

还有一个lambda表达式的例子,是list进行排序的,也借以表达lambda表达式可以有返回值的特性:

 Arrays.asList( "a", "b", "d" ).sort( ( e1, e2 ) -> {
int result = e1.compareTo( e2 );
return result;
} );

其实要是只是对list进行排序的话,上段代码可以简写成这样:

 Arrays.asList( "a", "b", "d" ).sort( ( e1, e2 ) -> e1.compareTo( e2 ) );

java的设计原本就参考了C++的诸多特性,lambda表达式也是源于对C++的模仿,但java 8中的lambda相对于C++中的而言,已经简化了很多,完整的C++的lambda表达式包括捕获列表、参数列表、箭头表达式、函数体以及尾置返回类型。有一个例子如下:

 int size_t=;
[size_t](const string src1, const string src1)—>{src1.size()<src2.size()};

2,Java的设计者们想了大量办法以使业已存在的功能支持lambda表达式,功能函数的概念便是其中之一。

函数接口(Functional Interface)是只含有一个方法的接口,我们经常使用的Runnable和Callable接口(这两个接口在多线程的环境下经常使用,两者最明显的区别就是Runnable无返回值,我们无法获取该线程的运算状态,而Callable则具有返回值,可以返回线程的运算结果。)便是最具代表性的例子。但是这两个接口是非常脆弱的,因为当开发人员往接口的定义里面再次添加方法声明时,已有实现该方法的类将不能够再运行。通过使用java注解@FunctionalInterface将使得接口具备这种能力,代码示例如下:

 @FunctionalInterface
public interface Functional {
void method();
}

在java 8中已经使接口Runnable和Callable接口添加了该注解。与此同时,java 8中提供的default和static方法不会对@FunctionalInterface接口产生影响。

3,下面了解一下java中的默认和静态方法。

学习语言最有效的方法之一就是学习优秀的代码实例,下面的就是优秀实例的其中之一:

 public interface DefaulableFactory {
// Interfaces now allow static methods
static Defaulable create( Supplier< Defaulable > supplier ) {
return supplier.get();
} private interface Defaulable {
// Interfaces now allow default methods, the implementer may or
// may not implement (override) them.
default String notRequired() {
return "Default implementation";
}
} private static class DefaultableImpl implements Defaulable {
} private static class OverridableImpl implements Defaulable {
@Override
public String notRequired() {
return "Overridden implementation";
}
} public static void main( String[] args ) {
Defaulable defaulable = DefaulableFactory.create( DefaultableImpl::new );
System.out.println( defaulable.notRequired() ); defaulable = DefaulableFactory.create( OverridableImpl::new );
System.out.println( defaulable.notRequired() );
} }

默认方法在函数定义的返回类型前面添加关键字default,同时添加了实现了功能的函数体。接口中的default方法使得实现了该接口的类可以不必实现该方法,当然也可以对其进行重写。

添加了默认方法的接口具有了java 5中抽象类所能够提供的功能,使得所有使用抽象类的地方都可以用拥有了default方法的接口取代,因此,不免让人遐想:抽象类在此之后还有存在的意义吗?!

同时,也要注意一下静态方法的参数及其使用。尤其是Supplier<Defaultable> supplier和DefaultableImp::new,这两种表达方式对java开发人员而言,还是挺新颖的。

4,可重复注解。

在java 8以前,相同类型的注解只能声明一次,例如在java开发的过程中,对某个方法重写,只能声明一次@override;在android构台过程中,对某个方法声明目标api,只有声明一次@targetapi。但是在java 8中,相同类型的注解却可以声明多次,示例代码如下:

 public class RepeatingAnnotations {
@Target( ElementType.TYPE )
@Retention( RetentionPolicy.RUNTIME )
public @interface Filters {
Filter[] value();
} @Target( ElementType.TYPE )
@Retention( RetentionPolicy.RUNTIME )
@Repeatable( Filters.class )
public @interface Filter {
String value();
}; @Filter( "filter1" )
@Filter( "filter2" )
public interface Filterable {
} public static void main(String[] args) {
for( Filter filter: Filterable.class.getAnnotationsByType( Filter.class ) ) {
System.out.println( filter.value() );
}
}
}

在main方法中,Fileterable接口通过反射机制来获取自身定义的注解,然后打印出来。

二,编译器新特性

1,参数名

长久以来java开发人员都在想尽各种办法以达到在运行时获取参数名字的目的,如今,java 8将此功能引入了java世界。

如下:

 public class ParameterNames {
public static void main(String[] args) throws Exception {
Method method = ParameterNames.class.getMethod( "main", String[].class );
for( final Parameter parameter: method.getParameters() ) {
System.out.println( "Parameter: " + parameter.getName() );
}
}
}

通过反射机制获取Parameter类,然后调用新增的方法getName来获取名字。

三,库新特性

1,Optional

NullPointerException(NPE)是引起应用崩溃的最著名的原因,这个估计每个开发人员都曾遇到过无数次。Google Guova项目组曾将Optional作为NPE的解决方案,受它的启发,java 8将Optional引入java库进来。

Optional仅仅是一个泛型容器:它保存一个T值或者是null,而且提供了大量的方法来检查null值。它的使用方式,正好有个例子:

 Optional< String > fullName = Optional.ofNullable( null );//Optional.of( "Tom" );
System.out.println( "Full Name is set? " + fullName.isPresent() );
System.out.println( "Full Name: " + fullName.orElseGet( () -> "[none]" ) );
System.out.println( fullName.map( s -> "Hey " + s + "!" ).orElse( "Hey Stranger!" ) );

第二行isPresent()表示Optional中保存的值是否为null;第三行orElseGet()表示如果为空将进行怎样的操作;第四行map()和orElse()表示如果Optional中的值不为空,则进行map里面的操作,否则的话执行orElse里面的操作。

2,日期时间API

java中的日期和时间API一直为开发人员所诟病,紧随Calendar之后的Date也没有改变这种状况。而开源java包Joda-Time却为这种状况进行了极大的改善,java -8中的日期与时间API则受到了Joda-Time极大的启发,并充分把它吸纳了进来。

java 8中的日期与时间API使用非常简单,一段代码就可以把它阐明,有一段代码如下:

 // Get the system clock as UTC offset
final Clock clock = Clock.systemUTC();
System.out.println( clock.instant() );
System.out.println( clock.millis() ); // Get the local date and local time
final LocalDate date = LocalDate.now();
final LocalDate dateFromClock = LocalDate.now( clock ); System.out.println( date );
System.out.println( dateFromClock ); // Get the local date and local time
final LocalTime time = LocalTime.now();
final LocalTime timeFromClock = LocalTime.now( clock ); System.out.println( time );
System.out.println( timeFromClock ); // Get the local date/time
final LocalDateTime datetime = LocalDateTime.now();
final LocalDateTime datetimeFromClock = LocalDateTime.now( clock ); System.out.println( datetime );
System.out.println( datetimeFromClock ); // Get the zoned date/time
final ZonedDateTime zonedDatetime = ZonedDateTime.now();
final ZonedDateTime zonedDatetimeFromClock = ZonedDateTime.now( clock );
final ZonedDateTime zonedDatetimeFromZone = ZonedDateTime.now( ZoneId.of( "America/Los_Angeles" ) ); System.out.println( zonedDatetime );
System.out.println( zonedDatetimeFromClock );
System.out.println( zonedDatetimeFromZone ); // Get duration between two dates
final LocalDateTime from = LocalDateTime.of( 2014, Month.APRIL, 16, 0, 0, 0 );
final LocalDateTime to = LocalDateTime.of( 2015, Month.APRIL, 16, 23, 59, 59 ); final Duration duration = Duration.between( from, to );
System.out.println( "Duration in days: " + duration.toDays() );
System.out.println( "Duration in hours: " + duration.toHours() );

3,Base64

终于,java把Base64加密/解密算法引入到最新版本中。使用如下:

 public class Base64s {
public static void main(String[] args) {
final String text = "Base64 finally in Java 8!"; final String encoded = Base64
.getEncoder()
.encodeToString( text.getBytes( StandardCharsets.UTF_8 ) );
System.out.println( encoded ); final String decoded = new String(
Base64.getDecoder().decode( encoded ),
StandardCharsets.UTF_8 );
System.out.println( decoded );
}
}

与此同时,java 8中的Base64也提供了对URL和MIME的加密/解密支持。(Base64.getUrlEncoder() / Base64.getUrlDecoder()Base64.getMimeEncoder() / Base64.getMimeDecoder())

4,并行数组

java 8提供了许多新的方法来支持对数组的并行处理,尤其是并行排序(parralelSort()),这种并行机制将充分利用处理品的多核机制,是对当前处理器发展趋势的顺应和完全把握。有个小例子如下:

 public class ParallelArrays {
public static void main( String[] args ) {
long[] arrayOfLong = new long [ 20000 ]; Arrays.parallelSetAll( arrayOfLong,
index -> ThreadLocalRandom.current().nextInt( 1000000 ) );
Arrays.stream( arrayOfLong ).limit( 10 ).forEach(
i -> System.out.print( i + " " ) );
System.out.println(); Arrays.parallelSort( arrayOfLong );
Arrays.stream( arrayOfLong ).limit( 10 ).forEach(
i -> System.out.print( i + " " ) );
System.out.println();
}
}

5,并发

并发常用的ConcurrentHashMap在java 8中改进了hash算法,降低了冲突的概率,当然,只是针对当键的类型为String的时候,其它类型键类型的冲突概率没有变化。

同时变化的并发用的类还有:ForkJoinPool,StampedLock,ReadWriteLock。新增的类有:DoubleAccumulator,DoubleAdder,LongAccumulator和LongAdder。

四,工具

java 8中新增加了两个工具,一个是js引擎工具(jjs),一个是类依存分析器(jdeps)。

例如一个js文件func.js,内容为function f(){return 1;}; print(f()+1);则在命令行中输入jjs func.js,就会输出2。

而对于jdeps工具,当输入一个 .class,文件夹或者.jar文件时,就会输出输入内容的类之间的依赖关系。例如输入:jdeps or.springframework.core-3.0.5.RELEASE.jar时,就会输出如下内容:

 org.springframework.core-3.0.5.RELEASE.jar -> C:\Program Files\Java\jdk1.8.0\jre\lib\rt.jar
org.springframework.core (org.springframework.core-3.0.5.RELEASE.jar)
-> java.io
-> java.lang
-> java.lang.annotation
-> java.lang.ref
-> java.lang.reflect
-> java.util
-> java.util.concurrent
-> org.apache.commons.logging not found
-> org.springframework.asm not found
-> org.springframework.asm.commons not found
org.springframework.core.annotation (org.springframework.core-3.0.5.RELEASE.jar)
-> java.lang
-> java.lang.annotation
-> java.lang.reflect
-> java.util

五,运行时(JVM)

在java 8中PermGen将不再存在,相反,Metaspace将会取代其位置。

JVM中-XX:PermSize和-XX:MaxPermSize将会被-XX:MetaSpaceSize和-XX:MaxMetaSpace取代。

总之,java 8的发布是java进化史上的一个重要的里程碑,java吸收了大量其它语言(尤其是c++)的优势,java 8也是今年java界最为令人激动的一件事。

本文参考许多其它的文章,地址附录如下,有兴趣的同行可以看一下:

http://www.javacodegeeks.com/2014/05/java-8-features-tutorial.html ;

http://www.javacodegeeks.com/2014/04/abstract-class-versus-interface-in-the-jdk-8-era.html ;

http://openjdk.java.net/jeps/180 ;

Java 8新特性前瞻的更多相关文章

  1. Java 8新特性-4 方法引用

    对于引用来说我们一般都是用在对象,而对象引用的特点是:不同的引用对象可以操作同一块内容! Java 8的方法引用定义了四种格式: 引用静态方法     ClassName :: staticMetho ...

  2. Spring 4支持的Java 8新特性一览

    有众多新特性和函数库的Java 8发布之后,Spring 4.x已经支持其中的大部分.有些Java 8的新特性对Spring无影响,可以直接使用,但另有些新特性需要Spring的支持.本文将带您浏览S ...

  3. java 8 新特性

    最近在IDEA的️驱使下,看了点java8的东西,链接贴一下,,,,, 1.Java 8新特性概述2.Java 8中的 Stream API 详解[3.Java 8新特性终极指南] 简单的使用看完新特 ...

  4. Java 8 新特性终极版

    声明:本文翻译自Java 8 Features Tutorial – The ULTIMATE Guide,翻译过程中发现并发编程网已经有同学翻译过了:Java 8 特性 – 终极手册,我还是坚持自己 ...

  5. Java 8新特性探究(八)精简的JRE详解

    http://www.importnew.com/14926.html     首页 所有文章 资讯 Web 架构 基础技术 书籍 教程 Java小组 工具资源 - 导航条 - 首页 所有文章 资讯 ...

  6. Java 8 新特性1-函数式接口

    Java 8 新特性1-函数式接口 (原) Lambda表达式基本结构: (param1,param2,param3) -> {代码块} 例1: package com.demo.jdk8; i ...

  7. 【整理】Java 8新特性总结

    闲语: 相比于今年三月份才发布的Java 10 ,发布已久的Java 8 已经算是老版本了(传闻Java 11将于9月25日发布....).然而很多报道表明:Java 9 和JJava10不是 LTS ...

  8. 一小时上手Java 8新特性

    一小时上手Java 8新特性 本文摘译自 https://www.journaldev.com/2389/java-8-features-with-examples,并做了适当增补. Iterable ...

  9. Java 8 新特性&colon;1-函数式接口

    (原) Java 8 新特性1-函数式接口 Lambda表达式基本结构: (param1,param2,param3) -> {代码块} Lambda表达式结构: (type1 arg1,typ ...

随机推荐

  1. Python 编码简单说

    先说说什么是编码. 编码(encoding)就是把一个字符映射到计算机底层使用的二进制码.编码方案(encoding scheme)规定了字符串是如何编码的. python编码,其实就是对python ...

  2. WebApi支持命名空间重名问题

    using System;using System.Collections.Concurrent;using System.Collections.Generic;using System.Linq; ...

  3. Altium Designer &sol;DXP无网络铺铜:

    有的设计者在PCB加工的时候会删除网络以便为了保护.但如果后续在无网络PCB上进行修改时就不叫麻烦,没有网络连铺铜都无法进行.一般手动添加网络只对要铺铜的地网络进行,其它的要修改者自己确保版图的正确性 ...

  4. 11gR2 RAC启用iptables导致节点宕机问题处理

    通常,在安装数据库时,绝大多数都是要求把selinux及iptables关闭,然后再进行安装的.但是在运营商的系统中,很多安全的因素,需要将现网的数据库主机上的iptables开启的. 在开启ipta ...

  5. for循环 重点题

    1.冒泡排序  (特别重要): <script type="text/javascript"> var attr=Array(); for(var i=0; i< ...

  6. npm包使用语义化版本号

    npm 采用语义版本管理软件包.所谓语义版本,就是指版本号为a.b.c的形式,其中a是大版本号,b是小版本号,c是补丁号. 一个软件发布的时候,默认就是1.0.0版.如果以后发布补丁,就增加最后一位数 ...

  7. 设置mysql远程连接

    https://www.cnblogs.com/linjiqin/p/5270938.html

  8. nginx request&lowbar;time 和upstream&lowbar;response&lowbar;time

    1.request_time 官网描述:request processing time in seconds with a milliseconds resolution; time elapsed ...

  9. layui前端框架之分页

    框架环境:SSM框架 为了保证效果,此次演示也用到了jQuery ui框架,大家最好也引入进来 一.去layui官网下载包,解压后,然后导入文件中,最好放再main/webapp文件夹下 官网地址如下 ...

  10. 斯坦福大学公开课机器学习:梯度下降运算的特征缩放(gradient descent in practice 1:feature scaling)

    以房屋价格为例,假设有两个特征向量:X1:房子大小(1-2000 feets), X2:卧室数量(1-5) 关于这两个特征向量的代价函数如下图所示: 从上图可以看出,代价函数是一个又瘦又高的椭圆形轮廓 ...