背景
方法是一堆宣告和業務邏輯代碼,回傳結果給呼叫者,方法也可以執行特定的邏輯,不回傳任何職給呼叫者,
方法能夠復用代碼,但是java里面的方法必須屬于某個類,
在看閉包之前,我們先復習一下lamada運算式,
lamada運算式是函式式介面的實體,lamda運算式實作了唯一的抽象方法,也就是實作了函式式介面,
如果函式式介面有多個抽象方法定義,就無法用lamada運算式實作多個方法,如下:

函式式介面(functional interface 也叫功能性介面,其實是同一個東西),簡單來說,函式式介面是只包含一個方法的介面,比如Java標準庫中的java.lang.Runnable和 java.util.Comparator都是典型的函式式介面,
備注:介面的方法都是抽象的,除非利用default關鍵字定義方法
interface GreetingService {
void sayMessage(String message);
default void sayMessage2(String mess){
}
}
我們看下面的例子:
package com.java.bitmap;
public class Java8Tester {
public static void main(String args[]){
Java8Tester tester = new Java8Tester();
// 不用括號
GreetingService greetService1 = message -> System.out.println("Hello " + message);
// 用括號
GreetingService greetService2 = (message) -> System.out.println("Hello " + message);
greetService1.sayMessage("Runoob");
greetService2.sayMessage("Google");
}
interface GreetingService {
void sayMessage(String message);
}
}
總結:
- 函式式介面就是僅定義一個抽象方法的介面,
- lamada運算式實作了僅有的抽象方法,也就是實作了函式式介面
lamada運算式作用:
- 能夠把方法作為函式引數
- 創建函式不屬于任何類
- lamada運算式能夠像物件一樣傳遞,按需執行
lamada運算式限制:lamada運算式的參考的外層變數都是final型別,無法改變值,否則會報錯,為了解決這個問題,閉包出現了,
閉包
定義
閉包函式:宣告在一個函式中的函式,叫做閉包函式,
閉包:內部函式總是可以訪問其所在的外部函式中宣告的引數和變數,即使在其外部函式被回傳(壽命終結)了之后,
我們來看JS里面的閉包定義,首先看下面的代碼:
function init() {
var name = 'Mozilla'; // name is a local variable created by init
function displayName() { // displayName() is the inner function, a closure
alert(name); // use variable declared in the parent function
}
displayName();
}
init();
上面代碼分析:
- name是init函式的區域變數,displayName方法沒有任何變數,但是作為init的內部函式,他可以訪問name變數
- 內部函式可以訪問外部函式的變數,但是反之,外部函式無法訪問內部函式的變數
修改后如下:
function makeFunc() {
var name = 'Mozilla';
function displayName() {
alert(name);
}
return displayName;
}
var myFunc = makeFunc();
myFunc();
myFunc是displayName的參考,在makeFunc執行的時候被創建的- 在makeFunc 執行結束后,我們仍然可以訪問name變數,這就是閉包的作用
閉包的作用
- 讓外部訪問函式內部變數成為可能;
- 區域變數會常駐在記憶體中;
- 可以避免使用全域變數,防止全域變數污染;
- 會造成記憶體泄漏(有一塊記憶體空間被長期占用,而不被釋放)
閉包例子
function funA(){
var a = 10; // funA的活動物件之中;
return function(){ //匿名函式的活動物件;
alert(a);
}
}
var b = funA();
b(); //10
function outerFn(){
var i = 0;
function innerFn(){
i++;
console.log(i);
}
return innerFn;
}
var inner = outerFn(); //每次外部函式執行的時候,都會開辟一塊記憶體空間,外部函式的地址不同,都會重新創建一個新的地址
inner();
inner();
inner();
var inner2 = outerFn();
inner2();
inner2();
inner2(); //1 2 3 1 2 3
var i = 0;
function outerFn(){
function innnerFn(){
i++;
console.log(i);
}
return innnerFn;
}
var inner1 = outerFn();
var inner2 = outerFn();
inner1();
inner2();
inner1();
inner2(); //1 2 3 4
Java中的閉包實作
(argument_list) -> {func_body}
e
edit
play_arrow
brightness_4
// Java program to demonstrate
// how a closure is implemented
// using lambda expressions
import java.io.*;
// Defining an interface whose
// implementation is given in
// the lambda expression.
// This uses the concept of
// closures
interface SalutationInterface {
public String salHello();
}
class GFG {
// Driver code
public static void main(String[] args)
{
// Lambda Expression
SalutationInterface obj = () ->
{
return "Hello, GFGians!";
};
// Calling the above interface
System.out.println(obj.salHello());
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/246523.html
標籤:其他
