Tips

【ローカル変数型推論】javaのvarの使い方~ラムダ式編~【java11】

【ローカル変数型推論】javaのvarの使い方~ラムダ式編~【java11】

javaのvarの使い方

javaのvarの使い方 ラムダ式編

変数・配列・Collectionはこちら 拡張for文編はこちら 注意点はこちら

変数・配列・Collectionに引き続き、ラムダ式(と、匿名クラス)でローカル変数型推論を利用した際の忘備録。

なお、本記事も、ひしだまのホームページ(外部リンク)様のこちらの記事を参考に、手元の環境で試した内容をもとに執筆しております。

 


javaの環境について

javaの環境は以下の通りです。

javaのバージョン
 openjdk version “11” 2018-09-25
 OpenJDK Runtime Environment 18.9 (build 11+28)
 OpenJDK 64-Bit Server VM 18.9 (build 11+28, mixed mode)
 javac 11

 

 プログラムを実行する際は自己責任で実行してください。 

 

以上、お約束のやつ終わり!

それでは早速行ってみよう!


サンプルプログラム

構文確認

サンプルプログラムの前に、ローカル変数型推論を使った際の構文の確認。

var 変数名 = 値; //OK
//var 変数名; //コンパイルエラー

 

通常の変数と異なり、 変数宣言時に必ず値を代入しないといけない ので注意!

構文を確認できたところで、使用例に行ってみよう♪


匿名クラスとラムダ式

//匿名クラスの場合、型推論が効くのでOK
var f1 = new Runnable(){
    @Override
    public void run(){
        System.out.println("f1.run()");
    }
};

//ラムダ式の場合、そのままでは型推論が効かないのでダメ。
//var f2 = () -> System.out.println("f2.run()");

//ラムダ式の場合でも、キャストすればOK
var f3 = (Runnable)() -> System.out.println("f3.run()");
 匿名クラスではキャスト不要 だが、 ラムダ式の場合はキャストが必要 

 

 

また、匿名クラスとラムダ式の場合で、以下のような違いもある。

//匿名クラスの場合
var f1 = new Runnable(){
    @Override
    public void run(){
        System.out.println("f1.run()");
    }
};

/*
//再度匿名クラスを実装して代入するとコンパイルエラー
f1 = new Runnable(){ //コンパイルエラー
    @Override
    public void run(){
        System.out.println("f1.run()#2");
    }
};
*/
//ラムダ式の場合
var f3 = (Runnable)() -> System.out.println("f3.run()");

//ラムダ式での場合、再代入可能。
f3 = (Runnable)() -> System.out.println("f3.run()#2");

以下、私見。
上記の違いは、匿名クラスで実装した場合はデータ型が「実装するごとに、元のクラス(インタフェース)を継承した新しいクラス」になるのに対して、ラムダ式の場合はキャストによってデータ型が「キャスト後のクラス(インタフェース)」になるため、と思われる。が、真相は闇の中(@_@)


メソッド参照

//var mr1 = "abc"::equals; //データ型の推論が効かない。キャストが必要。

var mr2 = (Predicate)"abc"::equals; //OK。

//var mr3 = (Boolean)"abc"::equals; //NG。メソッド参照なので、Boolean型ではなくPredicate型。

メソッド参照を利用する場合も、 データ型のキャストが必要 になるので注意。

上記の例ではメソッドそのものの戻り値ではなく、そのメソッドの 引数と戻り値に対応した関数型インタフェースにキャストしなければいけない ので注意。

うっかりBoolean型にキャストして小一時間悩んだのは内緒(@_@)


おまけ:for文

//for文の場合
//初期化部分で使用可能
for(var i = 0; i < 3; i++){
    System.out.print(i);
}

//ただし、初期化部分で複合宣言はできない。
/*for(var i = 0, j = 0; i < 3; i++){
    System.out.println(i + "-" + j);
}*/

for文の宣言部分でも使用可能。通常の変数同様に、 複合宣言できない ので注意。


 

以上、ラムダ式編でした♪

変数・配列・Collection編はこちら

拡張for文編はこちら

注意点はこちら

 


 オススメ!!→ java 11 の問題はこちら

 オススメ!!→ java のローカル変数型推論(var)の使い方はこちら 注意点はこちら

 オススメ!!→ java 8 の問題はこちら

 オススメ!!→ javaのプログラム作成練習問題はこちら

 オススメ!!→ java関連の記事はこちら

新連載はじまりました!新Java基礎 連載リンク

はじめてのJAVA 連載

Recent News

Recent Tips

Tag Search