【Java】JDK8新特性——Lambda表達式、函數式接口、接口默認(和靜態)方法

目錄

 

前言:

函數式接口

函數式接口規則:

Lambda表達式

語法:

Lambda表達式示列代碼

使用Lambda表達式注意

接口默認(和靜態)方法

接口默認方法重複問題解決


前言:

Oracle 公司於 2014 年 3 月 18 日發佈 Java 8,JDK8新特性函數式編程,

Lambda 表達式 − Lambda 允許把函數作爲一個方法的參數(函數作爲參數傳遞到方法中)。使用 Lambda 表達式可以使代碼變的更加簡潔緊湊。Lambda表達式就是用來簡化創建匿名內部接口對象的。

函數式接口 有函數式接口才能使用Lambda表達式。

默認(和靜態)方法 針對接口的,可以有自己的實現方法。

 

函數式接口

@FunctionalInterface
interface TestInterface {
    void sop(String message);
}

函數式接口要在接口上聲明標籤:

@FunctionalInterface

當然也可以不聲明此標籤,聲明此標籤的目的是爲了註明是函數式接口,在IDE上能自動檢查此類是否符合函數式接口規則。

函數式接口規則:

  1. 接口必須一定只能有一個抽象方法。(記住)。除了Object方法
  2. 除了接口能包含靜態方法和默認方法。(後面會講)

在瞭解完函數式接口,接下來就是如何使用Lambda表達式

 

Lambda表達式

Lambda表達式就是用來簡化創建內部接口對象的。

語法:

(聲明參數) -> {實現代碼}
  1. () 可選圓括號:情況一:無參方法,直接 () 表示。情況二:只有一個參數,可以忽略 ()。情況三:多個參數,必須用()圓括號,裏面用 , 英文逗號分開。
  2. -> 減 + 大於號:參數在左,實現在右。
  3. {} 可選大括號:情況一:主體只有一條語句,及只有一個 ; 分號的實現,可以忽略 {}。情況二:有返回值方法,並且主體只有一條返回值語句,及 ; 分號只有一個,可以忽略 {} 。情況三:有返回值的方法,一定要使用 {},則必須顯示聲明return。
  4. () 參數類型可選顯示化:可直接忽略參數類型,直接聲明變量名。如果顯示聲明參數類型必須配合 () 圓括號使用。

Lambda表達式示列代碼

package com.bin.demo;

@FunctionalInterface
interface NoValue {
	void nv();
}

@FunctionalInterface
interface Value {
	void v(int x, int y);
}

@FunctionalInterface
interface RValue {
	String rv(String value);
}

public class Main {

	public static void main(String[] args) {
		//無參創建
		NoValue nv = () -> System.out.println("雨煙");
		// 聲明參數類型
		Value v = (int x, int y) -> System.out.println("斌哥" + x + y);
		//不聲明參數類型
		Value v2 = (x, y) -> System.out.println("好想得到稱霸地球的力量" + x + y);
		//大括號返回值
		RValue rv = str -> {return "雷姆";};
		//無大括號返回值
		RValue rv2 = str -> "時崎狂三";
		
		//自動推斷的參數類型,並使用函數式參數
		sop(name -> name + "我想毀滅這個世界");
	}
	
	//常用於方法參數的 函數式參數傳遞
	private static void sop(RValue r) {
		System.out.println(r.rv("斌哥 sop -> "));
	}
	
}

輸出:

斌哥 sop -> 我想毀滅這個世界

使用Lambda表達式注意

  1. 創建的接口對象畢竟是 匿名內部類對象,在使用外層變量時,外層變量同樣要final修飾
  2. 聲明的參數名不允許相同。

如下示列會報錯:

package com.bin.demo;

@FunctionalInterface
interface Value {
	void v(int x, int y);
}

public class Main {

	public static void main(String[] args) {
		//未使用final修飾,並且外層類變量名與函數式內部類變量名相同。報錯
		int x = 1, y = 1;
		Value v = (int x, int y) -> System.out.println(x + y);
		Value v2 = (x, y) -> System.out.println(x + y);
		
		//糾正
		final int x = 1, y = 1;
		Value v = (int a, int b) -> System.out.println(x + y);
		Value v2 = (a, b) -> System.out.println(x + y);
	}
	
}

 

接口默認(和靜態)方法

就是在接口中顯示聲明關鍵字default修飾符默認方法,讓接口有自己的實現方法。

interface Value {
	default int to(int c, int b) {
		return c + b;
	}
	
	static void sop() {
		System.out.println("接口靜態方法");
	}
}

interface Value2 {
	default int to(int c, int b) {
		return c - b;
	}
}

接口默認方法重複問題解決

一個類實現了兩個接口,而兩個接口的默認方法是重複的(同名同參),這樣我們在創建這個類的對象時,該怎麼確定調用的是哪個默認方法呢?

這時候編譯器必須要求我們重寫不同接口的重名方法:

package com.bin.demo;

interface Value {
	default int to(int c, int b) {
		return c + b;
	}
	
	static void sop() {
		System.out.println("接口靜態方法");
	}
}

interface Value2 {
	default int to(int c, int b) {
		return c - b;
	}
}

class Test implements Value, Value2 {

	@Override
	public int to(int c, int b) {
                //允許使用 類名.super.方法() 的方式調用指定接口默認方法
		int c1 = Value.super.to(c, b);
		int c2 = Value2.super.to(c, b);
		System.out.println(c1);
		System.out.println(c2);
		return (c1 + c2);
	}
	
}

public class Main {

	public static void main(String[] args) {
		System.out.println(new Test().to(50, 20));
	}
	
}

通過使用 類名.super.方法() 的方式調用指定接口默認方法

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章