lambda表達式其實就是指一個匿名函數,應用最普遍的就是匿名內部類的簡化。在jdk1.8以前,咱們定義一個匿名內部類可能須要寫一大坨代碼,如今有了lambda以後,能夠寫的很簡潔了。但不是說lambda只能用來簡化匿名內部類,從lambda的實際做用和表現上來看,它就是一個變量指代了一個代碼塊。而可以使用lambda表達式的一個前提要求是,該變量必須實現某個函數式接口。啥是函數式接口?參考jdk1.8新特性之函數式接口。看一個匿名內部類的例子:html
FutureTask<String> coverTask = new FutureTask<String>(new Callable() { public String call() { return PortalBookCoverCacheService.getInstance().getBookCover(bookItem, PropertiesConfig.getProperty("cdnUrl")); } });
上面在實例化FutureTask對象的時候,使用了Callable接口實例的匿名內部類,實際上FutureTask構造器裏就是一個Callable的實例:java
Callable callable = new Callable() { public String call() { return PortalBookCoverCacheService.getInstance().getBookCover(bookItem, PropertiesConfig.getProperty("cdnUrl")); } };
若是咱們使用lambda表達式,上面的callable變量實際上就是dom
Callable callable = () -> { return PortalBookCoverCacheService.getInstance().getBookCover(bookItem, PropertiesConfig.getProperty("cdnUrl")); } ;
callable變量指代的就是一段代碼塊,把這個變量放入FutureTask的構造器裏,匿名內部類能夠簡化爲:函數
FutureTask<String> coverTask = new FutureTask<String>(() -> { return PortalBookCoverCacheService.getInstance() .getBookCover(bookItem, PropertiesConfig.getProperty("cdnUrl")); });
爲啥能這麼簡化呢?由於它符合lambda表達式規範,即Callable是一個函數式接口:spa
/** <a href="http://www.cpupk.com/decompiler">Eclipse Class Decompiler</a> plugin, Copyright (c) 2017 Chen Chao. */ /* * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. * * * * * * * * * * * * * * * * * * * * */ /* * * * * * * Written by Doug Lea with assistance from members of JCP JSR-166 * Expert Group and released to the public domain, as explained at * http://creativecommons.org/publicdomain/zero/1.0/ */ package java.util.concurrent; /** * A task that returns a result and may throw an exception. * Implementors define a single method with no arguments called * {@code call}. * * <p>The {@code Callable} interface is similar to {@link * java.lang.Runnable}, in that both are designed for classes whose * instances are potentially executed by another thread. A * {@code Runnable}, however, does not return a result and cannot * throw a checked exception. * * <p>The {@link Executors} class contains utility methods to * convert from other common forms to {@code Callable} classes. * * @see Executor * @since 1.5 * @author Doug Lea * @param <V> the result type of method {@code call} */ @FunctionalInterface public interface Callable<V> { /** * Computes a result, or throws an exception if unable to do so. * * @return computed result * @throws Exception if unable to compute a result */ V call() throws Exception; }
因此能夠咱們經過lambda表達式省略了接口類型、方法名和方法參數(由於這裏call方法根本就不須要參數),->符號的左邊是參數列表(若是有參數的話),右邊是方法體。lambda實際上是經過編譯器的強大而賦予的能力,編譯器經過自動匹配接口類型、智能識別參數列表,能夠像考古學家根據蛛絲馬跡恢復物品的原貌的同樣,還原出匿名內部類的原本面目。code