目次
为什么抽象类不能通过利用lambda实例化" >为什么抽象类不能通过利用lambda实例化
java.util.function
ホームページ Java &#&チュートリアル Java8の新機能は何ですか?

Java8の新機能は何ですか?

Jul 24, 2017 pm 04:53 PM
java8 特性

1. インターフェースの改善

a. 静的メソッドをインターフェースで定義できる

b. さらに重要なのは、インターフェース内のメソッドをデフォルトで変更してメソッド本体を追加できることです

2.デフォルトのメソッドは、equals、hashcode、toString メソッドですか?

つまり、インターフェースは Object クラスのメソッドのデフォルト実装を提供できません。クラスがメソッドを実装する場合、それは常にデフォルトの実装より優先されます。すべてのインターフェイス インスタンスが Object のサブクラスになると、すべてのインターフェイス インスタンスにはすでに、equals/hashCode/toString のデフォルト以外の実装が含まれます。したがって、インターフェイス上のこれらのデフォルト バージョンは役に立たず、コンパイルされません。

3. 関数型インターフェース

中心となる概念は関数型インターフェースです。インターフェイスが単一の抽象メソッドを定義する場合、そのインターフェイスは関数インターフェイスになります。たとえば、java.lang.Runnable は抽象メソッドを 1 つだけ定義しているため、関数型インターフェイスです:

public abstract void run();
 
ログイン後にコピー

関数型インターフェイスとは次の 2 つの状況があります: 1. インターフェイスには抽象メソッドが 1 つだけあり、抽象的な変更が含まれています。には、抽象メソッドである抽象変更が 1 つだけあります。同時に、デフォルト メソッドは抽象ではなくデフォルトで変更されるため、複数のデフォルト メソッドが含まれています。

同時に、新しいアノテーション @FunctionalInterface が導入されました。これをインターフェイスの前に置くと、インターフェイスが機能インターフェイスであることを示すことができます。インターフェイスを関数インターフェイスに変換しない限り、インターフェイスを追加してもコンパイルできません。これは @Override に似ており、誤って使用しないように使用する意図を宣言します。

4.Lambdas

関数型インターフェイスの非常に貴重な特性は、ラムダを使用してインスタンス化できることです。以下にラムダの例をいくつか示します。

左側は指定された型のコンマ区切りの入力リスト、右側は return を含むコード ブロックです。

(int x, int y) -> { return x + y; }
ログイン後にコピー

左側は、指定された型のコンマ区切りの入力リストです。派生型、右側が戻り値:

(x, y) -> x + y
ログイン後にコピー

左側が派生型の単一パラメータ、右側が戻り値:

x -> x * x
ログイン後にコピー

左側には入力がありません (正式名称) : "burger arrow")、右側に値が返されます:

() -> x
ログイン後にコピー

左側は導出型の単一パラメータ、右側は値を返さないコードのブロック (void を返す) :

x -> { System.out.println(x); }
ログイン後にコピー

静的メソッドリファレンス:

String::valueOf
ログイン後にコピー

非静的メソッドリファレンス:

Object::toString
ログイン後にコピー

継承関数リファレンス:

x::toString
ログイン後にコピー

コンストラクタリファレンス:

ArrayList::new
ログイン後にコピー

いくつかの関数を思いつくことができます参照形式は他のラムダの短縮形として機能しますフォーマット。

メソッドリファレンス 同等のラムダ式
String::valueOf x -> String.valueOf(x )
Object::toStringx -> rayList: :new
() -> new ArrayList<>()

  当然,在Java里方法能被重载。类可以有多个同名但不同参数的方法。这同样对构造方法有效。ArrayList::new能够指向它的3个构造方法中任何一个。决定使用哪个方法是根据在使用的函数式接口。

  一个lambda和给定的函数式接口在“外型”匹配的时候兼容。通过“外型”,我指向输入、输出的类型和声明检查异常。

给出两个具体有效的例子:

Comparator<String> c = (a, b) -> Integer.compare(a.length(),
                                                 b.length());
ログイン後にコピー

一个Comparator的compare方法需要输入两个阐述,然后返回一个int。这和lambda右侧的一致,因此这个任务是有效的。

Runnable r = () -> { System.out.println("Running!"); }
ログイン後にコピー

一个Runnable的run方法不需要参数也不会返回值。这和lambda右侧一致,所以任务有效。

在抽象方法的签名里的受检查异常(如果存在)也很重要。如果函数式接口在它的签名里声明了异常,lambda只能抛出受检查异常。

5.捕获和非捕获的Lanbdas表达式 

  当Lambda表达式访问一个定义在Lambda表达式体外的非静态变量或者对象时,这个Lambda表达式称为“捕获的”。比如,下面这个lambda表达式捕捉了变量x:

  int x = 5; return y -> x + y;
ログイン後にコピー

  为了保证这个lambda表达式声明是正确的,被它捕获的变量必须是“有效final”的。所以要么它们需要用final修饰符号标记,要么保证它们在赋值后不能被改变。

Lambda表达式是否是捕获的和性能悄然相关。一个非不捕获的lambda通常比捕获的更高效,虽然这一点没有书面的规范说明(据我所知),而且也不能为了程序的正确性指望它做什么,非捕获的lambda只需要计算一次. 然后每次使用到它都会返回一个唯一的实例。而捕获的lambda表达式每次使用时都需要重新计算一次,而且从目前实现来看,它很像实例化一个匿名内部类的实例。

6.其他

  lambdas不做的事

你应该记住,有一些lambdas不提供的特性。为了Java 8它们被考虑到了,但是没有被包括进去,由于简化以及时间限制的原因。

Non-final* 变量捕获 - 如果一个变量被赋予新的数值,它将不能被用于lambda之中。"final"关键字不是必需的,但变量必须是“有效final”的(前面讨论过)。这个代码不会被编译:

int count = 0;
List<String> strings = Arrays.asList("a", "b", "c");
strings.forEach(s -> {
    count++; // error: can&#39;t modify the value of count });
ログイン後にコピー
ログイン後にコピー

例外的透明度 - 如果一个已检测的例外可能从lambda内部抛出,功能性的接口也必须声明已检测例外可以被抛出。这种例外不会散布到其包含的方法。这个代码不会被编译:

void appendAll(Iterable<String> values, Appendable out) throws IOException { // doesn&#39;t help with the error values.forEach(s -> {out.append(s); // error: can&#39;t throw IOException here // Consumer.accept(T) doesn&#39;t allow it });}
ログイン後にコピー
ログイン後にコピー

有绕过这个的办法,你能定义自己的功能性接口,扩展Consumer的同时通过像RuntimeException之类抛出 IOException。我试图用代码写出来,但发现它令人困惑是否值得。

控制流程 (break, early return) -在上面的 forEach例子中,传统的继续方式有可能通过在lambda之内放置 "return;"来实现。但是,没有办法中断循环或者从lambda中通过包含方法的结果返回一个数值。例如:

final String secret = "foo"; boolean containsSecret(Iterable<String> values) {
    values.forEach(s -> { if (secret.equals(s)) {
            ??? // want to end the loop and return true, but can&#39;t }});
}
ログイン後にコピー
ログイン後にコピー

进一步阅读关于这些问题的资料,看看这篇Brian Goetz写的说明:在 Block中响应“已验证例外”Java8の新機能は何ですか?

其它翻译版本(1)

为什么抽象类不能通过利用lambda实例化

抽象类,哪怕只声明了一个抽象方法,也不能使用lambda来实例化。

下面有两个类 Ordering 和 CacheLoader的例子,都带有一个抽象方法,摘自于Guava 库。那岂不是很高兴能够声明它们的实例,像这样使用lambda表达式?

Ordering order = (a, b) -> ...;

CacheLoader<String, String> loader = (key) -> ...;
ログイン後にコピー
ログイン後にコピー

这样做引发的最常见的争论就是会增加阅读lambda的难度。以这种方式实例化一段抽象类将导致隐藏代码的执行:抽象类的构造方法。

另一个原因是,它抛出了lambda表达式可能的优化。在未来,它可能是这种情况,lambda表达式都不会计算到对象实例。放任用户用lambda来声明抽象类将妨碍像这样的优化。

外,有一个简单地解决方法。事实上,上述两个摘自Guava 库的实例类已经证明了这种方法。增加工厂方法将lambda转换成实例。

Ordering<String> order = Ordering.from((a, b) -> ...);
CacheLoader<String, String> loader = CacheLoader.from((key) -> ...);
ログイン後にコピー
ログイン後にコピー

要深入阅读,请参看由 Brian Goetz所做的说明: response to "Allow lambdas to implement abstract classes"。

java.util.function

包概要:java.util.function

作为Comparator 和Runnable早期的证明,在JDK中已经定义的接口恰巧作为函数接口而与lambdas表达式兼容。同样方式可以在你自己的代码中定义任何函数接口或第三方库。

但有特定形式的函数接口,且广泛的,通用的,在之前的JD卡中并不存在。大量的接口被添加到新的java.util.function 包中。下面是其中的一些:

  • Function -T作为输入,返回的R作为输出

  • Predicate -T作为输入,返回的boolean值作为输出

  • Consumer - T作为输入,执行某种动作但没有返回值

  • Supplier - 没有任何输入,返回T

  • BinaryOperator -两个T作为输入,返回一个T作为输出,对于“reduce”操作很有用

这些最原始的特征同样存在。他们以int,long和double的方式提供。例如:

  • IntConsumer -以int作为输入,执行某种动作,没有返回值

这里存在性能上的一些原因,主要释在输入或输出的时候避免装箱和拆箱操作。

你应该记住,有一些lambdas不提供的特性。为了Java 8它们被考虑到了,但是没有被包括进去,由于简化以及时间限制的原因。

Non-final* 变量捕获 - 如果一个变量被赋予新的数值,它将不能被用于lambda之中。"final"关键字不是必需的,但变量必须是“有效final”的(前面讨论过)。这个代码不会被编译:

int count = 0;
List<String> strings = Arrays.asList("a", "b", "c");
strings.forEach(s -> {
    count++; // error: can&#39;t modify the value of count });
ログイン後にコピー
ログイン後にコピー

例外的透明度 - 如果一个已检测的例外可能从lambda内部抛出,功能性的接口也必须声明已检测例外可以被抛出。这种例外不会散布到其包含的方法。这个代码不会被编译:

void appendAll(Iterable<String> values, Appendable out) throws IOException { // doesn&#39;t help with the error values.forEach(s -> {out.append(s); // error: can&#39;t throw IOException here // Consumer.accept(T) doesn&#39;t allow it });}
ログイン後にコピー
ログイン後にコピー

有绕过这个的办法,你能定义自己的功能性接口,扩展Consumer的同时通过像RuntimeException之类抛出 IOException。我试图用代码写出来,但发现它令人困惑是否值得。

控制流程 (break, early return) -在上面的 forEach例子中,传统的继续方式有可能通过在lambda之内放置 "return;"来实现。但是,没有办法中断循环或者从lambda中通过包含方法的结果返回一个数值。例如:

final String secret = "foo"; boolean containsSecret(Iterable<String> values) {
    values.forEach(s -> { if (secret.equals(s)) {
            ??? // want to end the loop and return true, but can&#39;t }});
}
ログイン後にコピー
ログイン後にコピー

进一步阅读关于这些问题的资料,看看这篇Brian Goetz写的说明:在 Block中响应“已验证例外”

Java8の新機能は何ですか?
Java8の新機能は何ですか?
翻译于 4年前
4人顶
翻译得不错哦!
其它翻译版本(1)

为什么抽象类不能通过利用lambda实例化

抽象类,哪怕只声明了一个抽象方法,也不能使用lambda来实例化。

下面有两个类 Ordering 和 CacheLoader的例子,都带有一个抽象方法,摘自于Guava 库。那岂不是很高兴能够声明它们的实例,像这样使用lambda表达式?

Ordering order = (a, b) -> ...;

CacheLoader<String, String> loader = (key) -> ...;
ログイン後にコピー
ログイン後にコピー

这样做引发的最常见的争论就是会增加阅读lambda的难度。以这种方式实例化一段抽象类将导致隐藏代码的执行:抽象类的构造方法。

另一个原因是,它抛出了lambda表达式可能的优化。在未来,它可能是这种情况,lambda表达式都不会计算到对象实例。放任用户用lambda来声明抽象类将妨碍像这样的优化。

外,有一个简单地解决方法。事实上,上述两个摘自Guava 库的实例类已经证明了这种方法。增加工厂方法将lambda转换成实例。

Ordering<String> order = Ordering.from((a, b) -> ...);
CacheLoader<String, String> loader = CacheLoader.from((key) -> ...);
ログイン後にコピー
ログイン後にコピー

要深入阅读,请参看由 Brian Goetz所做的说明: response to "Allow lambdas to implement abstract classes"。

Java8の新機能は何ですか?
Java8の新機能は何ですか?
翻译于 4年前
2人顶
 翻译得不错哦!
 

java.util.function

パッケージの概要: java.util.function

Comparator と Runnable の初期の証明として、JDK で既に定義されているインターフェイスは、たまたま関数インターフェイスとしてラムダ式と互換性があります。同様に、独自のコードで関数インターフェイスやサードパーティ ライブラリを定義できます。

しかし、広範囲かつ普遍的な、以前の JD カードには存在しなかった特定の形式の関数インターフェイスがあります。多数のインターフェースが新しい java.util.function パッケージに追加されました。その一部を次に示します:

  • Function -T を入力として、R を出力として返します

  • Predicate -T を入力として、ブール値を出力として返します

  • Consumer

  • Supplier - 入力として T を返し、出力として 1 つの T を返します。 「reduce」操作

  • これらの最も原始的な機能も存在します。これらは int、long、double として提供されます。例:

IntConsumer - int を入力として受け取り、何らかのアクションを実行し、戻り値はありません

  • ここにはパフォーマンス上の理由がいくつかありますが、主に入力または出力中のボックス化およびボックス化解除操作を回避するためです。

PMを待っていますJava8の新機能は何ですか? 4年前に翻訳
2
Peopleのトップ
トップ
良い翻訳です!
1
  • 2

  • 3

  • >

この記事のみのすべての翻訳学習とコミュニケーションを目的として、転載する際には必ず翻訳者、出典、およびこの記事へのリンクを明記してください
私たちの翻訳作業はCC規約に準拠しています。私たちの翻訳作業があなたの権利を侵害している場合は、すぐにご連絡ください
コメント (85
)

以上がJava8の新機能は何ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

Java 8で1年前または1年後の日付を計算するにはどうすればよいですか? Java 8で1年前または1年後の日付を計算するにはどうすればよいですか? Apr 26, 2023 am 09:22 AM

Java8 は、minus() メソッドを使用して 1 年前の日付または 1 年後の日付を計算し、1 年前の日付を計算します。 packagecom.shxt.demo02;importjava.time.LocalDate;importjava.time.temporal.ChronoUnit;publicclassDemo09{publicstaticvoidmain(String[ ]args ){LocalDatetoday=LocalDate.now();LocalDateprevious Year=today.minus(1,ChronoUni

win7 home バージョンと win7 Ultimate バージョンの違いの紹介 win7 home バージョンと win7 Ultimate バージョンの違いの紹介 Jul 12, 2023 pm 08:41 PM

win7システムには、win7Ultimateバージョン、Win7Professionalバージョン、Win7Homeバージョンなど、多くのバージョンがあることは誰もが知っています。多くのユーザーは、HomeバージョンとUltimateバージョンの間で迷っており、どのバージョンを選択すればよいかわかりません。そこで今日は、Win7 Family Meal と Win7 Ultimate の違いについて説明します。 1. Experience Different Home Basic Edition を使用すると、日常の操作がより迅速かつ簡単になり、最も頻繁に使用されるプログラムやドキュメントにより迅速かつ便利にアクセスできるようになります。 Home Premium は最高のエンターテインメント体験を提供し、お気に入りのテレビ番組、写真、ビデオ、音楽を簡単に楽しんだり共有したりできます。 Ultimate Edition は、各エディションのすべての機能を統合し、Windows 7 Home Premium のすべてのエンターテイメント機能とプロフェッショナル機能を備えています。

Spring MVC の主要な概念をマスターする: これらの重要な機能を理解する Spring MVC の主要な概念をマスターする: これらの重要な機能を理解する Dec 29, 2023 am 09:14 AM

SpringMVC の主要な機能を理解する: これらの重要な概念を習得するには、特定のコード例が必要です。 SpringMVC は、開発者が Model-View-Controller (MVC) アーキテクチャ パターンを通じて柔軟でスケーラブルな構造を構築するのに役立つ Java ベースの Web アプリケーション開発フレームワークです。ウェブアプリケーション。 SpringMVC の主要な機能を理解して習得すると、Web アプリケーションをより効率的に開発および管理できるようになります。この記事では、SpringMVC の重要な概念をいくつか紹介します。

Java 8を使用して1週間後の日付を計算するにはどうすればよいですか? Java 8を使用して1週間後の日付を計算するにはどうすればよいですか? Apr 21, 2023 pm 11:01 PM

Java8 で 1 週間後の日付を計算する方法 この例では、1 週間後の日付を計算します。 LocalDate 日付には時間情報が含まれません。その plus() メソッドは、日、週、月を追加するために使用されます。これらの時間単位は ChronoUnit クラスで宣言されます。 LocalDate も不変型なので、戻った後に変数を使用して値を割り当てる必要があります。 packagecom.shxt.demo02;importjava.time.LocalDate;importjava.time.temporal.ChronoUnit;publicclassDemo08{publicstaticvoidmain(String[

5gの3つの特徴とは 5gの3つの特徴とは Dec 09, 2020 am 10:55 AM

5g の 3 つの特徴は次のとおりです: 1. 高速; 実用的なアプリケーションでは、5G ネットワークの速度は 4G ネットワークの 10 倍以上です。 2. 低遅延; 5G ネットワークの遅延は約数十ミリ秒であり、人間の反応速度よりも高速です。 3. 幅広い接続: 5G ネットワークの出現と他のテクノロジーの組み合わせにより、すべてのインターネットの新しいシーンが生まれます。

Golang にはクラスのようなオブジェクト指向機能はありますか? Golang にはクラスのようなオブジェクト指向機能はありますか? Mar 19, 2024 pm 02:51 PM

Golang (Go 言語) には伝統的な意味でのクラスの概念はありませんが、構造体と呼ばれるデータ型が提供され、これによってクラスと同様のオブジェクト指向機能を実現できます。この記事では、構造体を使用してオブジェクト指向機能を実装する方法を説明し、具体的なコード例を示します。構造体の定義と使用法 まず、構造体の定義と使用法を見てみましょう。 Golang では、type キーワードを通じて構造を定義し、必要に応じて使用できます。構造には属性を含めることができます

ニーズと機能に基づいて、該当する Go バージョンを選択してください ニーズと機能に基づいて、該当する Go バージョンを選択してください Jan 20, 2024 am 09:28 AM

インターネットの急速な発展に伴い、プログラミング言語は常に進化し、更新されています。中でもGo言語はオープンソースのプログラミング言語として近年注目を集めています。 Go 言語は、シンプル、効率的、安全で、開発とデプロイが簡単になるように設計されています。高い同時実行性、高速なコンパイル、メモリの安全性などの特徴を備えており、Web開発、クラウドコンピューティング、ビッグデータなどの分野で広く使用されています。ただし、現在、Go 言語のさまざまなバージョンが利用可能です。適切な Go 言語バージョンを選択するときは、要件と機能の両方を考慮する必要があります。頭

C++ 関数の種類と特性 C++ 関数の種類と特性 Apr 11, 2024 pm 03:30 PM

C++ 関数には、単純関数、const 関数、静的関数、および仮想関数というタイプがあり、インライン関数、デフォルト パラメーター、参照戻り値、およびオーバーロードされた関数などの機能が含まれます。たとえば、calculateArea 関数は π を使用して、指定された半径の円の面積を計算し、それを出力として返します。

See all articles