felayman——网上搜集的有关于java8的新特性

Java 8 带来了多项重大更新,包括 Lambda 表达式、Nashorn 引擎、新的日期时间 API 等。其中,Lambda 表达式简化了多线程编程,并提高了代码的可读性和简洁性。

经过2年半的努力、屡次的延期和9个里程碑版本,甲骨文的Java开发团队终于发布了Java 8正式版本。

Java 8版本最大的改进就是Lambda表达式,其目的是使Java更易于为多核处理器编写代码;其次,新加入的Nashorn引擎也使得Java程序可以和JavaScript代码互操作;再者,新的日期时间API、GC改进、并发改进也相当令人期待。

另外,原本要加入Java 8的Jigsaw项目(标准模块系统)由于开发时间关系,被推迟到了Java 9中,不过Java 8已经在朝着这个方向努力了。
Java 8的所有新特性及改进包括(JEP全称为JDK Enhancement Proposal,JDK改进建议):

语言改进:

  • JEP 126:Lambda表达式 & 虚拟扩展方法
  • JEP 138:基于Autoconf的构建系统
  • JEP 160:针对Method Handles的Lambda形式的表征
  • JEP 161:简洁的配置文件
  • JEP 162:为模块化做准备
  • JEP 164:利用CPU指令来改善AES加密的性能
  • JEP 174:Nashorn引擎,允许在Java程序中嵌入JS代码
  • JEP 176:自动检测识别Caller-Sensitive方法
  • JEP 179:JDK API变化和稳定性记录
VM基础改进:

  • JEP 142:减少指定字段上的缓存争用
VM垃圾回收(vm/gc)改进:

  • JEP 122:移除Permanent Generation(永久代)
  • JEP 173:移除一些很少使用的垃圾回收器组合
VM运行时(vm/rt)改进:

  • JEP 136:提供更多的验证错误信息
  • JEP 147:减少类元数据封装
  • JEP 148:支持创建小型虚拟机(3M以下)
  • JEP 171:添加3个内存有序化的内联函数
核心基础(core)改进:

  • JEP 153:命令行启动JavaFX应用
核心lang(core/lang)改进:

  • JEP 101:目标类型推断
  • JEP 104:Java类型注解
  • JEP 105:DocTree API
  • JEP 106:在javax.tools中添加Javadoc
  • JEP 117:移除APT(Annotation-Processing Tool)
  • JEP 118:运行过程中可访问参数名
  • JEP 120:重复注解
  • JEP 139:增强了javac,以改善构建速度
  • JEP 172:DocLint工具,用来检查Javadoc注释内容
核心库(core/libs)改进:

  • JEP 103:并行数组排序
  • JEP 107:集合数据批量操作
  • JEP 109:增强的包含Lambda的核心库
  • JEP 112:改进了字符集的实现
  • JEP 119:Core Reflection提供的javax.lang.model实现
  • JEP 135:Base64编解码
  • JEP 149:减少了核心库的内存占用
  • JEP 150:日期时间API
  • JEP 155:改进对并发的支持
  • JEP 170:JDBC 4.2
  • JEP 177:java.text.DecimalFormat.format优化
  • JEP 178:静态链接的JNI库
  • JEP 180:使用平衡树处理频繁的HashMap碰撞
核心i18n(core/i18n)改进:

  • JEP 127:改进了本地数据封装,采用Unicode CLDR数据
  • JEP 128:BCP 47局部匹配
  • JEP 133:Unicode 6.2
核心net(core/net)改进:

核心安全(core/sec)改进:

  • JEP 113:MS-SFU Kerberos 5扩展
  • JEP 114:TLS Server Name Indication(SNI)扩展
  • JEP 115:AEAD密码套件
  • JEP 121:更强的口令加密系统算法
  • JEP 123:可配置的安全随机数生成方法
  • JEP 124:增强了证书撤回检测API
  • JEP 129NSA Suite B加密算法实现
  • JEP 130:SHA-224消息摘要算法实现
  • JEP 131:针对64位Windows的SunPKCS11加密提供程序
  • JEP 140:特权限制
  • JEP 166:彻底检修JKS-JCEKS-PKCS12密钥库
web/jaxp改进:

  • JEP 185:JAXP 1.5(限制获取外部资源)

Java8带有Lambda表达式的预览版的JDK已经放出来了(地址在最下面),新特性有以下四个:

1.Lambda表达式(或称之为“闭包”或者“匿名函数”)

2.扩展的目标类型

3.方法和构造器引用

4.接口默认方法

本文先介绍一下很值得期待的Lambda表达式,lambda表达式,等同于大多说动态语言中常见的闭包、匿名函数的概念。其实这个概念并不是多么新鲜的技术,在C语言中的概念类似于一个函数指针,这个指针可以作为一个参数传递到另外一个函数中。


由于Java是相对较为面向对象的语言,一个Java对象中可以包含属性和方法(函数),方法(函数)不能孤立于对象单独存在。这样就产生了一个问题,有时候需要把一个方法(函数)作为参数传到另外一个方法中的时候(比如回调功能),就需要创建一个包含这个方法的接口,传递的时候传递这个接口的实现类,一般是用匿名内部类的方式来。如下面代码,首先创建一个Runnable的接口,在构造Thread时,创建一个Runnable的匿名内部类作为参数:

Java代码
  1. newThread(newRunnable(){
  2. publicvoidrun(){
  3. System.out.println("hello");
  4. }
  5. }).start();

类似这种情况的还有swing中button等控件的监听器,如下面代码所示,创建该接口的一个匿名内部类实例作为参数传递到button的addActionListener方法中。

Java代码
  1. publicinterfaceActionListener{
  2. voidactionPerformed(ActionEvente);
  3. }
  4. button.addActionListener(newActionListener(){
  5. publicvoidactionPerformed(ActionEvente){
  6. ui.dazzle(e.getModifiers());
  7. }
  8. });

这样的代码的缺点是有代码笨重,可读性差,不能引用外面的非final的变量等。lambda表达式就是为了解决这类问题而诞生的。

在介绍Java8中的Lambda表达式之前,首先介绍一个概念叫“函数式接口”(functional interfaces)。对于任意一个Java接口,如果接口中只定义了唯一一个方法,那么这个接口就称之为“函数式接口”。比如JDK中的ActionListener、Runnable、Comparator等接口。

先来看一下Java8中的lambda表达式的使用示例:

创建一个线程:

Java代码
  1. newThread(()->{System.out.println("hello");}).start();

可以看到这段代码比上面创建线程的代码精简了很多,也有很好的可读性。

() -> {System.out.println("hello");} 就是传说中的lambda表达式,等同于上面的new Runnable(), lambda大体分为3部分:

1.最前面的部分是一对括号,里面是参数,这里无参数,就是一对空括号

2.中间的是 -> ,用来分割参数和body部分

3.是body部分,可以是一个表达式或者一个语句块。如果是一个表达式,表达式的值会被作为返回值返回;如果是语句块,需要用return语句指定返回值。如下面这个lambda表达式接受一个整形的参数a,返回a的平方

Java代码
  1. (inta)->a^2

等同于

Java代码
  1. (inta)->{returna^2;}

继续看更多的例子:

Java代码
  1. (intx,inty)->x+y
  2. ()->42
  3. (Strings)->{System.out.println(s);}

创建一个FileFilter,文件过滤器:

Java代码
  1. FileFilterjava=(Filef)->f.getName().endsWith(".java")

创建一个线程:

Java代码
  1. newThread(()->{
  2. //dosthhere...
  3. }).start()

创建一个Callable:

Java代码
  1. Callable<String>c=()->"done";

创建一个String的比较器:

Java代码
  1. Comparator<String>c=(s1,s2)->s1.compareToIgnoreCase(s2);

而且lambda表达式可以赋值给一个变量:

Java代码
  1. Comparator<String>c;
  2. c=(Strings1,Strings2)->s1.compareToIgnoreCase(s2);

还可以作为方法的返回值:

Java代码
  1. publicRunnabletoDoLater(){
  2. return()->{
  3. System.out.println("later");
  4. };
  5. }

从上面可以看到,一个lambda表达式被作为一个接口类型对待,具体对应哪个接口,编译器会根据上下文环境推断出来,如下面的lambda表达式就表示一个ActionListener.

Java代码
  1. ActionListenerl=(ActionEvente)->ui.dazzle(e.getModifiers());

这有可能会造成一个表达式在不同的上下文中被作为不同的类型,如下面的这种情况,尽管两个表达式是相同的,上面的表达式被推断为Callable的类型,下面的会被推断为PrivilegedAction类型。

Java代码
  1. Callable<String>c=()->"done";
  2. PrivilegedAction<String>a=()->"done";

那么编译器是根据哪些因为决定一个表达式的类型呢?

如果一个表达式被推断为是T类型的,需要满足以下4个条件:

1.T是函数式接口类型(只声明唯一一个方法)

2.表达式和T中声明的方法的参数个数一致,参数类型也一致

3.表达式和T中声明的方法的返回值类型一致

4.表达式和T中声明的方法抛出的异常一致

有了这个准则,上面的疑问就迎刃而解了

函数式接口。函数式接口是只定义了一个抽象方法的接口。Java 8引入了FunctionalInterface注解来表明一个接口打算成为一个函数式接口。例如,java.lang.Runnable就是一个函数式接口。

  Lambda。函数式接口的重要属性是:我们能够使用lambda实例化它们,Lambda表达式让你能够将函数作为方法参数,或者将代码作为数据对待。

  方法引用。方法引用是简洁的Lambda表达式,能够用于已经拥有名称的方法。下面是一些方法引用的例子,右边是同样效果的Lambda表达式。

  java.util.stream。新的 java.util.stream包提供了对值流进行函数式操作的类。

  改进了泛型推断。这提升了Java编译器推断泛型和在泛型方法调用中减少显式类型参数的能力。

  java.time。新的日期/时间API包含在 java.time包中。所有的类都是不可变且线程安全的。日期和时间类型包括Instant、LocalDate、LocalTime、LocalDateTime和ZonedDateTime。除了日期和时间之外,还有Duration和Period类型。另外,值类型包括Month、DayOfWeek、Year、 Month、YearMonth、MonthDay、OffsetTime和OffsetDateTime。这些新的日期/时间类大部分JDBC都支持。

  当然,以上只是一小部分新特性,关于Java 8的相关信息,请点此查看

  Jigsaw项目被推迟到Java SE 9

  “对于Java开发者来说,Java 8意味着一次重大的转变。”JFrog公司CTO Yoav Landman表示,“JDK 8加入了Lambda表达式以及方法引用,这会让程序变得更加简单。”

  IDC分析师Al Hilwa也表示,加入Lambda是Java的一次重要变化,这对于并行编程来说将非常有益。“虽然给编程语言带来了很大的影响,但Lambda仅仅是增加并行化编程能力的一部分。”

  JDK 8原定于去年9月发布,但由于安全问题,Oracle推迟到了今年3月份。此外,原本计划加入的Project Jigsaw,也推迟到了Java SE 9上,这让很多Java开发者失望不已

  此外, 国外媒体也针对JDK 8进行了一项调查,主要面向Java中间件厂商。调查结果显示,有29%的公司计划六个月内升级到最新版本;有25%公司会在十二个月内完成升级;有32%的公司还未对新版本进行评估;同时,也有22%的企业还在使用在2006年发布的Java SE 6。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值