1概要

この記事では、Java 8の最も興味深い新機能について簡単に説明します。

ここでは、インターフェイスのデフォルトメソッドと静的メソッド、メソッド参照、およびOptionalについて説明します。

Java 8のリリースのいくつかの機能 –

ストリームAPI



lambda式と関数型インターフェース

– について別の外観に値する包括的なトピックです。


2インタフェースのデフォルトおよび静的メソッド

Java 8以前は、インタフェースはパブリック抽象メソッドしか持てませんでした。すべての実装クラスに新しいメソッドの実装を作成させることなく、既存のインタフェースに新しい機能を追加することはできませんでした。また、実装を持つインタフェースメソッドを作成することもできませんでした。

Java 8以降、インターフェースは


static


および


default


メソッドを持つことができます。これらのメソッドは、インターフェース内で宣言されていても定義済みの動作を持ちます。

** 2.1. 静的メソッド

インターフェースの次のメソッドを考えます(このインターフェースを

Vehicle

と呼びましょう)。

static String producer() {
    return "N&F Vehicles";
}

静的

producer()

メソッドは、インタフェースを通して、または内部でのみ利用可能です。実装クラスによってオーバーライドすることはできません。

インターフェースの外でそれを呼び出すためには、静的メソッド呼び出しのための標準的なアプローチが使われるべきです:

String producer = Vehicle.producer();


2.2. デフォルトの方法

デフォルトのメソッドは新しい


default

キーワード

を使って宣言されます。これらは実装クラスのインスタンスを通してアクセス可能で、オーバーライドすることができます。


Vehicle

インターフェースに

default

メソッドを追加しましょう。これにより、このインターフェースの

static

メソッドも呼び出されます。

default String getOverview() {
    return "ATV made by " + producer();
}

このインタフェースが__VehicleImplクラスによって実装されていると仮定します。

Vehicle vehicle = new VehicleImpl();
String overview = vehicle.getOverview();

** 3メソッド参照

メソッド参照は、既存のメソッドを呼び出すだけのラムダ式の、短くて読みやすい代替手段として使用できます。メソッド参照には4つの種類があります。


3.1. 静的メソッドへの参照

静的メソッドへの参照は、次の構文を保持します。


  • ContainingClass :: methodName .

    **

Stream APIを使用して、

List <String>

内のすべての空の文字列を数えましょう。

boolean isReal = list.stream().anyMatch(u -> User.isRealUser(u));


filter()

メソッドのラムダ式をよく見てください。これは

User

クラスの静的メソッド

isRealUser(User user)

を呼び出すだけです。そのため、静的メソッドへの参照で置き換えることができます。

boolean isReal = list.stream().anyMatch(User::isRealUser);

この種のコードは、はるかに有益に見えます。


3.2. インスタンスメソッドへの参照

インスタンスメソッドへの参照は、次の構文を保持します。

  • c

    __ontainingInstance :: methodName .


    ** 次のコードは、入力パラメータを検証する

    User

    型のメソッド

    isLegalName(String string)__を呼び出します。

User user = new User();
boolean isLegalName = list.stream().anyMatch(user::isLegalName);


3.3. 特定の種類のオブジェクトのインスタンスメソッドへの参照

この参照メソッドは次の構文を取ります。

  • C


    _ontainingType :: methodName .

    _

    ** 例::

long count = list.stream().filter(String::isEmpty).count();


3.4. コンストラクタへの参照

コンストラクターへの参照は次の構文を取ります。

  • ClassName


    _ :: new .



    Javaのコンストラクタは特別なメソッドなので、メソッド名



    .


    として

    new_

    ** を利用してメソッド参照を適用することもできます。

Stream<User> stream = list.stream().map(User::new);


4.



オプションの<T>


Java 8以前は、

NullPointerException(NPE)

がスローされる可能性があるため、開発者は参照した値を慎重に検証する必要がありました。これらすべてのチェックは、かなり厄介でエラーを起こしやすい定型コードを要求しました。

Java 8

Optional <T>

クラスは、

NPEを取得する可能性がある状況を処理するのに役立ちます。

T型のオブジェクトのコンテナとして機能します。

null

。このコンテナ内の値が

null

の場合、__NPEをスローするのではなく、定義済みのアクションを実行できます。


4.1.

Optional <T>


の作成


Optional

クラスのインスタンスは、その静的メソッドを使用して作成できます。

Optional<String> optional = Optional.empty();

空の__Optionalを返します。

String str = "value";
Optional<String> optional = Optional.of(str);

null以外の値を含む

Optional

を返します。

Optional<String> optional = Optional.ofNullable(getString());

特定の値で

Optional

を返すか、パラメータが

nullの場合は空の

Optional__を返します。


4.2.

オプション<T>

使用法

たとえば、

List <String>

を取得し、

null

の場合は、それを__ArrayList <String>の新しいインスタンスに置き換えたいと思います。

List<String> list = getList();
List<String> listOpt = list != null ? list : new ArrayList<>();

Java 8では、はるかに短いコードで同じ機能を実現できます。

List<String> listOpt = getList().orElseGet(() -> new ArrayList<>());

古い方法でオブジェクトのフィールドに到達する必要がある場合は、さらに定型コードがあります。

Address

型のフィールドと

String型のフィールドs


treet


を持つ

User

型のオブジェクトがあるとします。何らかの理由で

street

フィールドの値を返す必要があるか、

street



null__の場合はデフォルト値を返す必要があります。

User user = getUser();
if (user != null) {
    Address address = user.getAddress();
    if (address != null) {
        String street = address.getStreet();
        if (street != null) {
            return street;
        }
    }
}
return "not specified";

これは

Optional:

で単純化できます。

Optional<User> user = Optional.ofNullable(getUser());
String result = user
  .map(User::getAddress)
  .map(Address::getStreet)
  .orElse("not specified");

この例では、

map()

メソッドを使用して、

getAdress()

の呼び出し結果を

Optional <Address>

に、

getStreet()



Optional <String>に変換しています。 )

メソッドは空の

Optional.

を返します。

私たちのゲッターが

Optional <T>を返すことを想像してください。それで、

map()の代わりに

flatMap()

メソッドを使うべきです:__

Optional<OptionalUser> optionalUser = Optional.ofNullable(getOptionalUser());
String result = optionalUser
  .flatMap(OptionalUser::getAddress)
  .flatMap(OptionalAddress::getStreet)
  .orElse("not specified");


Optional

の別のユースケースは、別の例外を除いて

NPE

を変更することです。

それで、以前と同じように、これをJava 8以前のスタイルで試してみましょう。

String value = null;
String result = "";
try {
    result = value.toUpperCase();
} catch (NullPointerException exception) {
    throw new CustomException();
}

また、

Optional <String>

を使用した場合はどうなりますか?答えはもっと読みやすくそしてより簡単です:

String value = null;
Optional<String> valueOpt = Optional.ofNullable(value);
String result = valueOpt.orElseThrow(CustomException::new).toUpperCase();

アプリで

Optional

をどのようにどのような目的で使用するかは、重大で物議を醸す設​​計上の決定であり、そのすべての長所と短所の説明はこの記事の範囲外です。あなたが興味を持っているなら、あなたはより深く掘り下げることができます、この問題に捧げられたインターネット上のたくさんの興味深い記事があります。


This one

およびhttp://blog.joda.org/2015/08/java-se-8- optional-pragmatic-approach.html[このもう1つ]は非常に役に立ちます。


5結論

この記事では、Java 8の興味深い新機能について簡単に説明します。

他の多くの追加や改良がもちろんあり、それらは多くのJava 8 JDKパッケージやクラスに広がっています。

しかし、この記事に示されている情報は、これらの新機能のいくつかを調べて学ぶための良い出発点です。

最後に、記事のすべてのソースコードが利用可能です

over on
GitHub。