函數式接口就是隻有一個抽象方法的接口。若是這個接口裏沒有或者包含了兩個以上的抽象方法,對不起,你不叫函數式接口,只能叫你接口。那這個函數式有啥用呢?若是配合Lambda表達式的話,能夠大大的簡化代碼。這裏不說Lambda,只說函數式接口,先看它長啥樣:html
/* * Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved. * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. * * * * * * * * * * * * * * * * * * * * */ package java.lang; /** * The <code>Runnable</code> interface should be implemented by any * class whose instances are intended to be executed by a thread. The * class must define a method of no arguments called <code>run</code>. * <p> * This interface is designed to provide a common protocol for objects that * wish to execute code while they are active. For example, * <code>Runnable</code> is implemented by class <code>Thread</code>. * Being active simply means that a thread has been started and has not * yet been stopped. * <p> * In addition, <code>Runnable</code> provides the means for a class to be * active while not subclassing <code>Thread</code>. A class that implements * <code>Runnable</code> can run without subclassing <code>Thread</code> * by instantiating a <code>Thread</code> instance and passing itself in * as the target. In most cases, the <code>Runnable</code> interface should * be used if you are only planning to override the <code>run()</code> * method and no other <code>Thread</code> methods. * This is important because classes should not be subclassed * unless the programmer intends on modifying or enhancing the fundamental * behavior of the class. * * @author Arthur van Hoff * @see java.lang.Thread * @see java.util.concurrent.Callable * @since JDK1.0 */ @FunctionalInterface public interface Runnable { /** * When an object implementing interface <code>Runnable</code> is used * to create a thread, starting the thread causes the object's * <code>run</code> method to be called in that separately executing * thread. * <p> * The general contract of the method <code>run</code> is that it may * take any action whatsoever. * * @see java.lang.Thread#run() */ public abstract void run(); }
它最明顯的一個標誌就是FunctionalInterface註解,若是你使用了FunctionalInterface註解卻在接口裏寫了兩個抽象方法,那麼編譯器是不會放過你的。固然咱們也能夠不加該註解,只要你知足了一個抽象方法的接口這個標準,那麼它仍然是函數式接口:java
/* * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. * * * * * * * * * * * * * * * * * * * * */ package java.lang; import java.util.Iterator; import java.util.Objects; import java.util.Spliterator; import java.util.Spliterators; import java.util.function.Consumer; /** * Implementing this interface allows an object to be the target of * the "for-each loop" statement. See * <strong> * <a href="{@docRoot}/../technotes/guides/language/foreach.html">For-each Loop</a> * </strong> * * @param <T> the type of elements returned by the iterator * * @since 1.5 * @jls 14.14.2 The enhanced for statement */ public interface Iterable<T> { /** * Returns an iterator over elements of type {@code T}. * * @return an Iterator. */ Iterator<T> iterator(); /** * Performs the given action for each element of the {@code Iterable} * until all elements have been processed or the action throws an * exception. Unless otherwise specified by the implementing class, * actions are performed in the order of iteration (if an iteration order * is specified). Exceptions thrown by the action are relayed to the * caller. * * @implSpec * <p>The default implementation behaves as if: * <pre>{@code * for (T t : this) * action.accept(t); * }</pre> * * @param action The action to be performed for each element * @throws NullPointerException if the specified action is null * @since 1.8 */ default void forEach(Consumer<? super T> action) { Objects.requireNonNull(action); for (T t : this) { action.accept(t); } } /** * Creates a {@link Spliterator} over the elements described by this * {@code Iterable}. * * @implSpec * The default implementation creates an * <em><a href="Spliterator.html#binding">early-binding</a></em> * spliterator from the iterable's {@code Iterator}. The spliterator * inherits the <em>fail-fast</em> properties of the iterable's iterator. * * @implNote * The default implementation should usually be overridden. The * spliterator returned by the default implementation has poor splitting * capabilities, is unsized, and does not report any spliterator * characteristics. Implementing classes can nearly always provide a * better implementation. * * @return a {@code Spliterator} over the elements described by this * {@code Iterable}. * @since 1.8 */ default Spliterator<T> spliterator() { return Spliterators.spliteratorUnknownSize(iterator(), 0); } }
雖然上面接口除了一個抽象方法(接口裏方法的默認修飾符是public abstract)外,還有兩個默認方法,但它依然知足只有一個抽象方法的標準。除了默認方法,靜態方法、Object對象裏的方法(接口默認繼承java.lang.Object,因此若是接口顯示聲明覆蓋了Object中方法,那麼也不算抽象方法),都不要緊。less