java8的新特性_Java8的

java8的新特性

Java8没有安排释放,直到2014年3月,但早期发行版本已经可用了一段时间。 一些最有趣的新功能是:

  • 功能接口
  • 默认方法
  • Lambdas
  • Java时间


新的java.util.stream软件包包含“支持元素流上的功能样式操作的类”。 流不是一种新的集合,并且不替换任何现有的集合,例如列表和队列。 相反,它们提供了一种与现有集合进行交互的方式,并且在这方面与迭代器更相似。

javadocs将流描述为“支持顺序和并行聚合操作的元素序列”。 流管道由产生结果(例如,总和或计数)的源(例如,集合),中间操作(例如,过滤器或映射)和终端操作组成。 流是惰性的,因为对数据的操作仅在最后一分钟(即,在调用终端操作时)执行,并且流仅处理一次。

例如:

int totalFxTrading = blocks.stream()
        .filter(trade -> trade.getType() == FX)
        .mapToInt(b -> b.getTradedAmount())
        .sum();

功能接口

Java 8将具有称为功能接口的新功能。 功能接口只有一种抽象方法。 您可能已经将许多这样的接口用作Java开发人员,例如Runnable,ActionListener,Comparator和Callable。 在Java 8中,这些类型的接口现在更正式地称为功能接口。 可以使用新的@FunctionalInterface批注来标识它们,最重要的是,可以使用Lambda表达式(稍后再介绍)来表示它们。 例如,过去要使用ActionListener,需要创建一个实现,通常使用匿名内部类。

例如:

JButton button = new JButton();
        button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent ae) {
                System.out.println(ae.getSource());
            }
        });

使用功能接口,这变得更加简单:

JButton myButton = new JButton();
        button.addActionListener(
            ae -> {System.out.println("You clicked the button");}
        );

我们甚至不需要提及ActionEvent –编译器从上下文中得出“ ae”的类型。 请注意, @ FunctionalInterface批注(如@Override批注)不是必需的。 相反,它向编译器发出信号,表明您的意图,以便在某些地方出现问题(例如多个抽象方法可用)时向您发出警告。

默认方法

在Java7之前,接口是相当简单的事情。 它只能包含必须由具体子类实现的抽象方法(和常量)。 接口基本上是一堆方法签名,但是永远不能包含方法定义/实现。

在Java8中,事情变得更加有趣。 现在可以将默认方法添加到接口。 这些是具有实现的方法,不必在接口实现中重写,并且可以直接从接口运行。

添加这些默认方法是为了提供向后兼容性。 如果未添加它们,则例如在不破坏所有实现的情况下就不可能扩展/改善现有的收集接口。 因此,由于这个原因,默认方法有时称为防御者方法。

对我来说,默认方法的真正有趣之处在于它们允许多种形式的继承。 由于一个类可以实现多个接口,并且每个接口现在都可以具有一个具有相同名称的默认方法,因此该子类可以继承哪个版本? 我认为这被称为钻石问题 。 如果在使用Java8时出现这种情况,编译器将提供警告。 您可以使用语法X.super.m(…)显式选择父类的实现之一。

附带说明一下,为什么这些新的默认方法完全需要default关键字? 如果没有该关键字,他们是否也能正常工作? 答案是肯定的,默认关键字是多余的,就像抽象关键字一样。 两者都被添加以使事情更加清晰。 这篇文章有一些更多的细节是链接。

拉姆达

根据Wikipedia的说法,lambda表达式是“定义为不绑定标识符的函数”。 Lambda表达式已进入Java版本,旨在简化代码。

我上面讨论的许多其他更改(默认方法,功能接口)与引入lambas密切相关。

编写Lambda表达式时,它将在编译时转换为功能接口。 这是一个使用Lambda表达式用更简洁易读的代码替换匿名内部类的示例。
没有Lambda的旧方法:

button.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent ae) {
            System.out.println(“Action Detected”);
        }
    });

Lambda的新方法:

button.addActionListener(e -> {
        System.out.println(“Action Detected”);
    });

使用Lambda表达式通常会使代码更易于阅读,并且所需的行数更少。

Java时间

用Java处理日期和时间从来都不是理想的。 充其量,它是古怪的,而最糟的是,它是一场噩梦。 Date类很笨重,现在已被不推荐使用的方法所困扰。 Calendar类是一种改进,但是我个人似乎总是花更多的时间来浏览API文档,即使我以前做过这些事情。 其他第三方图书馆则尝试以更简洁的方式处理时间(例如,乔达时间)。 有传言说Java8和Java8改进了Java itslef和anf的处理,这就是java.time包。

一个新的(抽象)Clock类提供了一些有用的静态方法,例如systemUTC()和systemDefaultZone()来获取当前时间和时区。 并且许多新类(例如LocalDate和LocalTime以及YearMonth和MonthDay)提供了更为优雅的日常(对双关语)日期操作。

可以在JSR-310站点上找到更多详细信息。

Java8中没有的内容

在一个侧面说明,虽然日期/时间的处理将在Java8得到改善,令人惊讶的还有没有好的办法来处理货币的Java(东西我已经在博客 ,在过去)。 双打(以及所有浮点数)天生就不适合花钱,或者需要精确计算的任何地方。 使用int或long需要跟踪小数点,BigDecimal也不理想。 JSR-354可能会有所改进,但看起来我们必须等到Java 9才能完成。

参考:来自Shaun Abram博客博客的JCG合作伙伴 Shaun Abram的Java8

翻译自: https://www.javacodegeeks.com/2013/10/java8.html

java8的新特性

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值