Oracle发布JDK 15/Java 15 下载+新特性介绍

来源:CNBETA  责任编辑:小易  

【注意】本文节选自是 DZone 指南&#8194;Java 生态系统的专题文章,作者Trisha Gee是Java资深工程师和布道者32313133353236313431303231363533e58685e5aeb931333339666137。在本文中,Trisha Gee阐述了Java 8的重要特性以及使用的原因,由OneAPM工程师翻译。一、要点速递1、在很多情况下,Java8 都能提升应用性能,而无需任何改变或性能调优。2、 Lambda 表达式、 Streams API 以及现有类的新方法都是提高生产力的重要工具。3、Java8 新推出的 Optional 类型在处理 null 值时,能减少 NullPointerExceptions 的可能性,给开发者极大的灵活度。二、其他特性:速度更快可以取悦老板、满足业务或运营人员的一大卖点是:Java8 运行应用时速度更快。通常,升级至 Java8 的应用都能得到速度上的提升,即便没有做任何改变或调优。对于为了迎合特定 JVM 而做出调整的应用,这或许并不适用。但 Java8 性能更优的理由还有很多:80%以上的高端企业级应用都使用JAVA平台(电信、银行等)。JAVA是成熟的产品,已经有10年的历史。如果你想在Java行业有所建树,想要系统的进行java的学习,那么你可以来这个群,前面是二三一,中间是三一四,后面是零二八。连起来就可以了。 这里有很多互联网大牛教你学习,还有免费的课程。不是想学习的就不要加了。常见数据结构的性能提升:对广受欢迎的 HashMap 进行的基准测试表明,它们在 Java8 中的性能更好。这种提升非常吸引人——你无需学习新的 Streams API 或 Lambda 语法,甚至不需要改变现有的代码,就能提升应用的性能。垃圾回收器提升:通常,Java 应用性能取决于垃圾回收的效率。的确,糟糕的垃圾回收会很大程度上影响应用性能。Java8 对垃圾回收做了很多改变,能有效提升性能并简化调优。最为人熟知的改变是 PermGen 的移除与 Metaspace 的引入。Fork/Join 速度提升:fork/join 框架是在 Java7 中首次引入的,目的是简化使用 JVM 的并发程序。Java8 中投入了很多努力进一步提升该框架。现在,fork/join 在 Streams API 中用于并发操作。此外,Java8 中还包含诸多改进以支持并发。Oracle 在 JDK 8 中总结了这些性能提升。代码行更少Java 经常被人们诟病其样本代码太多。为此,Java8 新的 API 采用了更具功能性的方式,专注于实现什么而不是如何实现。Lambda 表达式Java8 中的 Lambda 表达式不仅是 Java 已有的匿名内部类—— Java8 推出之前传递行为的方法之外的语法糖衣。Lambda 表达式采用了 Java 7 的内部改变,因此运用起来相当流畅。想了解如何使用 Lambda 表达式简化代码,请继续阅读。集合新方法介绍Lambda 表达式与 Streams 可能是 Java8 最大的两个卖点,较少为人知的是 Java 现在允许开发者给现有类添加新的方法,而无需为了向后兼容性折中。这样,新的方法,结合 Lambda 表达式,能在很大程序上简化代码。比如,我们常常需要判断 Map 中的某个成员是否已经存在,如果不存在则创建之。在 Java8 之前,你可能会这么做:private final Map<CustomerId, Customer> customers = new HashMap<>();   public void incrementCustomerOrders(CustomerId customerId) {  Customer customer = customers.get(customerId);  if (customer == null) {      customer = new Customer(customerId);      customers.put(customerId, customer);  }  customer.incrementOrders();  }操作“检查某个成员在 map 中是否存在,若不存在则添加之”是如此常用,Java 现在为 Map 添加了一个新方法 computeIfAbsent 来支持这个操作。该方法的第二个参数是一个 Lambda 表达式,该表达式定义了如何创建缺少的成员。public void incrementCustomerOrders(CustomerId customerId) {  Customer customer = customers.computeIfAbsent(customerId,         id -> new Customer(id));  customer.incrementOrders();  }其实,Java8 还有一个新的特性,称为方法引用(method references),它能使我们用更简洁的代码实现该功能:public void incrementCustomerOrders(CustomerId customerId) {  Customer customer = customers.computeIfAbsent(customerId, Customer::new);  customer.incrementOrders();  }Java8 为 Map 与 List 都添加了新方法。你可以了解一下这些新方法,看它们能节省多少行代码。Streams APIStreams API 为查询、操纵数据提供了更多灵活度。这是一个很强大的功能。阅读这些文章能对 Streams API 有更全面的了解。在大数据时代建立流畅的数据查询会非常有趣,而且也是常用的操作。比如,你有一列书,你希望按照字母表顺序排列这些书的作者名,且不含重复。public List<Author> getAllAuthorsAlphabetically(List<Book> books) {  List<Author> authors = new ArrayList<>();  for (Book book : books) {      Author author = book.getAuthor();      if (!authors.contains(author)) {          authors.add(author);      }  }  Collections.sort(authors, new Comparator<Author>() {      public int compare(Author o1, Author o2) {          return o1.getSurname().compareTo(o2.getSurname());      }  });  return authors;  }在上面的代码中,我们首先遍历这列书,如果书的作者从未在作者列表出现,则添加之。之后,我们根据作者的姓氏按字母表顺序对这些作者排序。这种排序操作正是 Streams 擅长解决的领域:public List<Author> getAllAuthorsAlphabetically(List<Book> books) {  return books.Streams()              .map(book -> book.getAuthor())              .distinct()              .sorted((o1, o2) -> o1.getSurname().compareTo(o2.getSurname()))              .collect(Collectors.toList());  }上面的做法不仅代码行更少,而且描述性更强——后来的开发者读到这段代码能够轻易理解:1、代码从书中获取作者姓名。2、只在意从未出现过的作者。3、返回的列表按照作者姓氏排序。将 Streams API 与其他新特性——方法引用(method references)、比较器(Comparator)的新方法结合使用,可以得到更加简洁的版本:public List<Author> getAllAuthorsAlphabetically(List<Book> books) {  return books.Streams()              .map(Book::getAuthor)              .distinct()              .sorted(Comparator.comparing(Author::getSurname))              .collect(Collectors.toList());  }这里,排序方法按照作者姓氏排序,更加显而易见了。便于并行此前我们浅聊过更利于开箱即用的性能,除了前面提到过的特性,Java8 能更好地利用 CPU 内核。将前例中的 Streams 方法替换为 parallelStreams,JVM 会将此运算分解为不同的任务,使用 fork/join 将这些任务运行在多个核上。然而,并行化并不是加速所有运算的魔法。并行化运算总是会带来更多工作——分解运算,整合结果,因此无法总是减少时间。但是,对适合并行化的例子,这么做还是颇有效率的。最大化减少 Null 指针Java8 的另一个新特性是全新的 Optional 类型。该类型的含义是“我可能有值,也可能是 null。“这样一来,API 就可以区分可能为 null 的返回值与绝对不会是 null 的返回值,从而最小化 NullPointerException 异常的发生几率。Optional 最赞的用处是处理 null。例如,假设我们要从一个列表中找一本特定的书,新创建的 findFirst() 方法会返回 Optional 类型的值,表明它无法确保是否找到特定的值。有了这个可选择的值,我们接下来可以决定,如果是 null 值要如何处理。如果想要抛出一个自定义的异常,我们可以使用 orElseThrow:public Book findBookByTitle(List<Book> books, String title) {  Optional<Book> foundBook = books.Streams()         .filter(book -> book.getTitle().equals(title))         .findFirst();  return foundBook.orElseThrow(() -> new BookNotFoundException("Did not find book with title " + title));  }    或者,你可以返回其他书:return foundBook.orElseGet(() -> getRecommendedAlternativeBook(title));或者,返回 Optional 类型,这样,该方法的调用者可以自己决定书没找到时要怎么做。总结:Java8 作为 Java 语言的一次重大发布,包含语法上的更改、新的方法与数据类型,以及一些能默默提升应用性能的隐性改善。Oracle 已经不再支持 Java 7,因此许多公司都被迫向 Java8 转移。好消息是,Java8 对业务、现有的应用以及期望提高生产力的开发者都好好多。本回答被提问者采纳,随着编程语言生态系32313133353236313431303231363533e4b893e5b19e31333433623830统的气候不断变化以及技术的革新,经历20余年的发展,Java逐渐演变成长为Java8。相比之前只是单纯的面向对象编程语言,Java8增加了很多新特性。 Java 8对于程序员的主要好处在于它提供了更多的编程工具和概念,能以更为简洁、更易于维护的方式解决新的或现有的编程问题。在Java 8中有两个著名的改进:一个是Lambda表达式,一个是Stream。 Lambda表达式是什么?Lambda表达式,也可称为闭包,它允许把函数作为一个方法的参数(函数作为参数传递进方法中)。使用Lambda表达式可以使代码变的更加简洁紧凑,Lambda表达式的语法格式:(parameters) -> expression或(parameters) ->{ statements; } Lambda表达式的重要特征:可选类型声明:不需要声明参数类型,编译器可以统一识别参数值。可选的参数圆括号:一个参数无需定义圆括号,但多个参数需要定义圆括号。可选的大括号:如果主体包含了一个语句,就不需要使用大括号。可选的返回关键字:如果主体只有一个表达式返回值则编译器会自动返回值,大括号需要指定明表达式返回了一个数值。 使用Lambda表达式需要注意以下两点:Lambda表达式主要用来定义行内执行的方法类型接口,例如,一个简单方法接口。在上面例子中,我们使用各种类型的Lambda表达式来定义MathOperation接口的方法。然后我们定义了sayMessage的执行。Lambda表达式免去了使用匿名方法的麻烦,并且给予Java简单但是强大的函数化的编程能力。Stream是什么?Stream就是一个流,它的主要作用就是对集合数据进行查找过滤等操作。Java 8中的 Stream是对集合(Collection)对象功能的增强,它专注于对集合对象进行各种非常便利、高效的聚合操作(aggregate operation),或者大批量数据操作(bulk data operation)。 对于基本数值型,目前有三种对应的包装类型Stream:IntStream、LongStream、DoubleStream。当然我们也可以用Stream<Integer>、Stream<Long> >、Stream<Double>,但是boxing和 unboxing会很耗时,所以特别为这三种基本数值型提供了对应的Stream。Java 8中还没有提供其它数值型Stream,因为这将导致扩增的内容较多。而常规的数值型聚合运算可以通过上面三种Stream进行。 Stream上的操作分为两类:中间操作和结束操作。中间操作只是一种标记,只有结束操作才会触发实际计算。中间操作又可以分为无状态的(Stateless)和有状态的(Stateful),无状态中间操作是指元素的处理不受前面元素的影响,而有状态的中间操作必须等到所有元素处理之后才知道最终结果,比如排序是有状态操作,在读取所有元素之前并不能确定排序结果。结束操作又可以分为短路操作和非短路操作,短路操作是指不用处理全部元素就可以返回结果,比如找到第一个满足条件的元素。之所以要进行如此精细的划分,是因为底层对每一种情况的处理方式不同。 想要永远处于优势地位,就要不断的完善自身、更新技术www.zgxue.com防采集请勿采集本网。

访问:

阿里云推出高校特惠专场:0元体验入门云计算 快速部署创业项目

“JDK1.5”(开发代号猛2113虎)的一个重要主题就是通过新增一些5261特性来简化4102开发,这些特性包括1653泛型,for-else 循环,自动装包/拆包,枚举,可变参数, 静态导入 。使用这些特性有助于我们编写更加清晰,精悍,安全的代码。 下面我们简单介绍一下这些新特性。 1.泛型(Generic) C++通过模板技术可以指定集合的元素类型,而Java在1.5之前一直没有相对应的功能。一个集合可以放任何类型的对象,相应地从集合里面拿对象的时候我们也不得不对他们进行强制得类型转换。猛虎引入了泛型,它允许指定集合里元素的类型,这样你可以得到强类型在编译时刻进行类型检查的好处。Collection<String> c = new ArrayList();c.add(new Date()); 编译器会给出一个错误:add(java.lang.String) in java.util.Collection<java.lang.String> cannot be applied to (java.util.Date) 2.For-Each循环 For-Each循环得加入简化了集合的遍历。假设我们要遍历一个集合对其中的元素进行一些处理。典型的代码为:void processAll(Collection c){ for(Iterator i=c.iterator(); i.hasNext();){ MyClass myObject = (MyClass)i.next(); myObject.process(); }} 使用For-Each循环,我们可以把代码改写成:void processAll(Collection<MyClass> c){ for (MyClass myObject :c) myObject.process();} 这段代码要比上面清晰许多,并且避免了强制类型转换。3.自动装包/拆包(Autoboxing/unboxing) 自动装包/拆包大大方便了基本类型数据和它们包装类地使用。 自动装包:基本类型自动转为包装类.(int >> Integer) 自动拆包:包装类自动转为基本类型.(Integer >> int) 在JDK1.5之前,我们总是对集合不能存放基本类型而耿耿于怀,现在自动转换机制解决了我们的问题。int a = 3;Collection c = new ArrayList();c.add(a);//自动转换成Integer.Integer b = new Integer(2);c.add(b + 2); 这里Integer先自动转换为int进行加法运算,然后int再次转换为Integer. 4.枚举(Enums) JDK1.5加入了一个全新类型的“类”-枚举类型。为此JDK1.5引入了一个新关键字enmu. 我们可以这样来定义一个枚举类型。 public enum Color{ Red, White, Blue} 然后可以这样来使用Color myColor = Color.Red. 枚举类型还提供了两个有用的静态方法values()和valueOf(). 我们可以很方便地使用它们,例如for (Color c : Color.values()) System.out.println(c); 5.可变参数(Varargs) 可变参数使程序员可以声明一个接受可变数目参数的方法。注意,可变参数必须是函数声明中的最后一个参数。假设我们要写一个简单的方法打印一些对象,util.write(obj1);util.write(obj1,obj2);util.write(obj1,obj2,obj3);… 在JDK1.5之前,我们可以用重载来实现,但是这样就需要写很多的重载函数,显得不是很有效。如果使用可变参数的话我们只需要一个函数就行了public void write(Object... objs) { for (Object obj: objs) System.out.println(obj);} 在引入可变参数以后,Java的反射包也更加方便使用了。对于c.getMethod("test", new Object[0]).invoke(c.newInstance(), new Object[0])),现在我们可以这样写了c.getMethod("test").invoke(c.newInstance()),这样的代码比原来清楚了很多。 6.静态导入(Static Imports) 要使用用静态成员(方法和变量)我们必须给出提供这个方法的类。使用静态导入可以使被导入类的所有静态变量和静态方法在当前类直接可见,使用这些静态成员无需再给出他们的类名。import static java.lang.Math.*;…….r = sin(PI * 2); //无需再写r = Math.sin(Math.PI); 不过,过度使用这个特性也会一定程度上降低代码地可读性,范型和annotation,在swing里面有几个,但是想不起来了,还有泛型啊内容来自www.zgxue.com请勿采集。


  • 本文相关:
  • 谁给我介绍一些jdk1.5以后的新特性
  • Java8新特性有哪些?
  • java 1.7 的新特性在官网哪儿可以查看啊?
  • Oracle 19c新特性介绍及优化实践
  • 免责声明 - 关于我们 - 联系我们 - 广告联系 - 友情链接 - 帮助中心 - 频道导航
    Copyright © 2017 www.zgxue.com All Rights Reserved