This is an excerpt from Java 8 in Action by Raoul-Gabriel Urma, Mario Fusco and Alan Mycroft, a Manning publication available here . JAXenter readers can get a 39% discount by using the following code: jejava8
自1996年发布JDK 1.0(Java 1.0)以来,Java赢得了许多活跃用户的学生,项目经理和程序员的支持。 它是一种表达性语言,并且继续用于大型和小型项目。 从Java 1.1(1997)到Java 7(2011)的演变(通过添加新功能)得到了很好的管理。 Java 8于2014年3月发布。问题是:您为什么要关心Java 8? 我们认为Java 8的变化在许多方面都比Java历史上的任何其他变化都要深刻。 好消息是,所做的更改使您可以更轻松地编写程序-而不是像下面这样编写冗长的代码(根据重量对清单中的苹果进行排序),
Collections.sort(inventory, new Comparator<Apple>() {
public int compare(Apple a1, Apple a2){
return a1.getWeight().compareTo(a2.getWeight());
}
});
在Java 8中,您可以编写更简洁的代码,使其更接近问题陈述:
inventory.sort(comparing(Apple::getWeight));
它显示为“比较库存,比较苹果重量”。 现在不用担心此代码。 还有一个硬件影响:商用CPU已成为多核-便携式计算机或台式机中的处理器中可能有四个或更多CPU内核。 但是,绝大多数现有的Java程序仅使用这些内核之一,而使其他三个处于空闲状态(或将其处理能力的一小部分用于运行部分操作系统或病毒检查程序)。
在Java 8之前,专家可能会告诉您,必须使用线程才能使用这些核心。 问题是使用线程很困难并且容易出错。 Java遵循了一条不断发展的道路,即不断尝试使并发变得更容易且错误更少。 Java 1.0具有线程和锁,甚至还有一个内存模型(这是当时的最佳实践),但是事实证明,这些原语很难在非专业项目团队中可靠地使用。 Java 5添加了诸如线程池和并发集合之类的行业实力构建块。 Java 7添加了fork / join框架,使并行性更加实用,但仍然很困难。 Java 8具有一种新的,更简单的方式来考虑并行性。 但是您仍然必须遵循一些规则,您将在本书中学习这些规则!
从这两个示例(更简洁的代码和更简单的多核处理器的使用)中汲取了Java 8的整个一致大厦。我们首先简要介绍一下这些想法(希望足以引起您的兴趣,但又足够简短,可以概括它们) :
- Streams API
- 将代码传递给方法的技巧
- 接口中的默认方法
Java 8提供了一个新的API(称为Streams),该API支持许多并行操作来处理数据,并且类似于您在数据库查询语言中的思维方式-您以更高的方式表达了您想要的内容以及实现(此处是Streams库) )选择最佳的底层执行机制。 结果,它避免了您编写使用同步代码的需求,这不仅容易出错,而且比您在多核CPU上可能实现的成本还要高。¹
从稍微修正主义的观点来看,Java 8中Streams的添加可以看作是Java 8中另外两项添加的直接原因:简洁的技术将代码传递给方法(方法引用,lambda)和接口中的默认方法。
但是,仅将流代码传递给方法的想法就淡化了它在Java 8中的使用范围。它为您提供了一种表达行为参数化的简洁新方法。 假设您要编写两种仅在几行代码中有所不同的方法; 现在,您只需传递作为参数的不同部分的代码即可(这种编程技术比使用复制和粘贴的常见趋势更短,更清晰且出错率更低)。 专家将在这里注意到,在Java 8之前,可以使用匿名类对行为参数化进行编码-但我们将在本章第一页的示例中使用Java 8增强代码简洁性来说明问题明晰!
Java 8将代码传递给方法的功能(还能够返回代码并将其合并到数据结构中)还提供了对通常称为功能样式编程的全部附加技术的访问。 简而言之,这样的代码(在函数式编程社区中称为函数)可以被传递和组合,以产生功能强大的编程习惯用法,您将在本书的 Java 8中看到这些习惯用法。
为什么Java仍在变化?
1960年代出现了对完美编程语言的追求。 当时的著名计算机科学家Peter Landin在1966年的一篇具有里程碑意义的文章2中指出,已经有700种编程语言,并推测下700种编程语言是什么样的-包括类似于Java 8的函数式编程的参数。
后来,成千上万种编程语言的学者得出结论,即编程语言的行为就像一个生态系统:除非出现新的语言,否则会取代旧的语言。 我们都希望有一种完美的通用语言,但实际上,某些语言更适合某些领域。 例如,由于C和C ++的运行时占用空间小,并且尽管缺少2 PJ Landin,“ The Next 700 Programming Languages”,CACM 9(3):157,但它们在构建操作系统和各种其他嵌入式系统中仍然很流行。 – 1966年3月–65。6第1章Java 8:您为什么要关心? 编程安全性。 缺乏安全性可能导致程序意外崩溃,并暴露出病毒等安全漏洞。 实际上,当可以接受额外的运行时占用空间时,诸如Java和C#之类的类型安全语言已在各种应用程序中取代了C和C ++。
事先占领利基市场往往会使竞争对手望而却步。 更改为新的语言和工具链通常仅是一项功能就太痛苦了,但是新手最终将取代现有的语言,除非它们发展得足够快以跟上(老读者经常能够引用他们所使用的一系列此类语言)。 '以前曾经编码过,但其知名度此后有所下降-Ada,Algol,COBOL,Pascal,Delphi和SNOBOL,仅举几例。
您是一名Java程序员,并且Java在过去15年中已经成功地在大型的编程任务生态系统中殖民(并取代了竞争对手的语言)。 让我们检查一些原因。
Java在编程语言生态系统中的地位
Java启动良好。 从一开始,它就是一种经过精心设计的面向对象的语言,其中包含许多有用的库。 它还从一开始就支持小规模并发,它对线程和锁提供了集成支持(并以硬件中立的内存模型的形式提前确认了多核处理器上的并发线程还可能具有意外行为)。到单核处理器上发生的情况)。 此外,决定将Java编译为JVM字节码(一种虚拟机代码,不久每个浏览器都支持该虚拟机代码)意味着它已成为Internet小程序程序的首选语言(您还记得小程序吗?)。
实际上,存在Java虚拟机(JVM)及其字节码比Java语言本身更重要的危险,并且对于某些应用程序,Java可能会被其竞争性语言之一(例如Scala或Groovy)取代,也可以在JVM上运行。 JVM的各种最新更新(例如,JDK7中新的invokedynamic字节码)旨在帮助此类竞争者语言在JVM上平稳运行,并与Java互操作。 Java还成功地占领了嵌入式计算的各个方面(从智能卡,烤面包机,机顶盒到汽车制动系统的所有方面)。
Java是如何进入通用编程领域的?
面向对象在1990年代变得很流行,其原因有两个:封装原理导致的软件工程问题比C少。 作为一种思维模型,它可以轻松捕获Windows 95及更高版本的WIMP编程模型。
可以总结如下:一切都是对象; 鼠标单击将事件消息发送到处理程序(在Mouse对象中调用Clicked方法)。 Java的一次写入无处不在的模型以及早期浏览器能够(安全)执行Java代码小程序的能力使它在大学中占有一席之地,大学的毕业生随后进入了行业。 最初对Java比C / C ++的额外运行成本有抵制,但是机器变得越来越快,程序员的时间变得越来越重要。 微软的C#进一步验证了Java风格的面向对象模型。
![气候变化Java](https://i-blog.csdnimg.cn/blog_migrate/cebf417462cece4a285c11d9c1ceb5ad.png)
图1.1 –编程语言生态系统和气候变化
但是,编程语言生态系统的气候正在发生变化。 程序员越来越多地处理所谓的大数据(TB级及更高级别的数据集),并希望有效利用多核计算机或计算集群来对其进行处理。 这意味着使用并行处理-Java以前不友好的东西。
您可能会遇到其他编程领域的编程思想(例如Google的map-reduce或使用SQL这样的数据库查询语言进行数据操作的相对简便性),可帮助您处理大量数据和多核CPU。 图1.1以图形方式总结了语言生态系统:将景观视为编程问题的空间,并将特定地面的优势植被作为该程序的最爱语言。 气候变化是指新硬件或新编程会产生影响的想法(例如,“为什么不能以类似SQL的风格编程?”)意味着不同的语言成为新项目的选择语言,就像区域温度升高意味着如今,葡萄在较高的纬度地区蓬勃发展。 但是当然有滞后现象-许多老农夫将继续种植传统农作物。 总而言之,由于新语言已经Swift适应了气候变化,因此出现并变得越来越流行。
Java 8对程序员的主要好处在于,它提供了更多的编程工具和概念,可以更快或更重要地以更简洁,更易于维护的方式解决新的或现有的编程问题。 尽管这些概念对于Java来说是新的,但在类似利基研究的语言中已被证明具有强大的功能。 我们重点介绍和开发了三个这样的编程概念背后的思想,这些思想驱动了Java 8功能的开发,以利用并行性并通常编写更简洁的代码。 我们以与本书其余部分稍有不同的顺序介绍它们,以实现基于Unix的类比并在Java 8的多核新并行性中公开“因此而需要”的依赖关系。
¹多核CPU的每个处理器核心都具有单独的缓存(快速内存)。 锁定要求将它们同步,从而需要相对较慢的缓存一致性协议核心间通信。
翻译自: https://jaxenter.com/why-is-java-still-changing-119535.html