Functional Interface

Functional Interface是什么?

功能接口是java 8中的新增功能,它们只允许一个抽象方法。这些接口也称为单抽象方法接口(SAM接口)。这些也可以使用Lambda表达式,方法引用和构造函数引用来表示。Java 8也引入了一个注释,即@FunctionalInterface,当你注释的接口违反了Functional Interface的契约时,它可以用于编译器级错误。

Tips:如果你想强制当前接口只保留一个抽象方法,就可以使用@FunctionalInterface,它可以帮我们通过编译错误提示用户必须不能声明超过一个抽象方法

构建我们第一个默认接口:

@FunctionalInterface
public interface MyFuntinoalInterface<T> { public void eat();
/**
* 超过一个抽象方法会编译报错,可以把下面注释去掉查看效果
*/
//public void play();
}

尝试将上例的注释去掉,可以发现,超过两个抽象方法会直接报编译错误

@FunctionalInterface
public interface MyFuntinoalInterface<T> { public void eat();
/**
* 超过一个抽象方法会编译报错,可以把下面注释去掉查看效果
*/
public void play();
}

报如下编译异常:

功能接口的使用原则

  • 在任何功能接口中只允许一种抽象方法。功能界面中不允许使用第二种抽象方法。如果我们删除@FunctionInterface注释,那么我们可以添加另一个抽象方法,但它会使接口成为非功能性接口。
  • 即使省略@FunctionalInterface注释,功能接口也是有效的。它仅用于通知编译器在接口内强制执行单个抽象方法。
  • 从概念上讲,功能界面只有一种抽象方法。由于默认方法具有实现,因此它们不是抽象的。由于默认方法不是抽象的,因此您可以根据需要随意添加默认方法到功能接口。

你可以添加多个默认方法到功能接口中,但是它不会计入抽象方法的数量:

@FunctionalInterface
public interface MyFuntinoalInterface<T> { public void eat(); default void run(){
System.out.println("跑步");
} default void swim(){
System.out.println("游泳");
}
}
  • 功能接口里可以有多个覆盖java.lang.Objectd的抽象方法,它不会计入接口的抽象方法数量。
@FunctionalInterface
public interface MyFuntinoalInterface<T> { public void eat(); /**
* 重写Object方法不会算入抽象方法统计
* @return
*/
@Override
public String toString();
}

JDK 中的功能接口

JDK1.8开始支持功能接口,以下可以举几个例子,功能接口主要是配合lambda表达式使用,具体介绍会在后续的lambda表达式章节也会提到

Comparator

@FunctionalInterface
public interface Comparator<T>

在JDK1.8中,主要对Comparator接口添加了默认方法,对Comparator实现类添加了很多新特性方法

Consumer

@FunctionalInterface
public interface Consumer<T>

相信大家查看JDK1.8源码会发现,很多类都有Consumer这个接口存在,在JDK1.8中更多是提供各个接口支持lambda表达式使用

Iterable

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);
}
}

Iterable虽然接口头上没有@FunctionalInterface注解标注,它这里只有一个抽象方法,默认也是一个功能接口,在JDK1.8中新添加了支撑lambda表达式的默认方法

Java8新特性一点通 | 回顾功能接口Functional Interface的更多相关文章

  1. Java8新特性一点通 | 回顾字符转日期&JoinArray使用

    StringToDate日期转换 Join Array使用 StringToDate日期转换 Convert string to date in ISO8601 format 利用LocalDate. ...

  2. Java8新特性一点通 | 回顾文件操作和watchService文件变更监视操作

    文件操作 WatchService 文件操作 今天重温了一些文件操作: - Files.list() 遍历文件和目录 //List all files and sub-directories usin ...

  3. Java8新特性—四大内置函数式接口

    Java8新特性--四大内置函数式接口 预备知识 背景 Lambda 的设计者们为了让现有的功能与 Lambda 表达式良好兼容,考虑了很多方法,于是产生了函数接口这个概念. 什么是函数式接口? 函数 ...

  4. java8新特性—四大内置核心接口

    java8新特性-四大内置核心接口 四大内置核心接口 //消费型接口 Consumer<T>:: vode accept(T t); //供给型接口 Supplier<T>:: ...

  5. Java8新特性_lambda表达式和函数式接口最详细的介绍

    Lambda表达式 在说Lambda表达式之前我们了解一下函数式编程思想,在数学中,函数就是有输入量.输出量的一套计算方案,也就是“拿什么东西做什么事情”. 相对而言,面向对象过分强调“必须通过对象的 ...

  6. Java8新特性时间日期库DateTime API及示例

    Java8新特性的功能已经更新了不少篇幅了,今天重点讲解时间日期库中DateTime相关处理.同样的,如果你现在依旧在项目中使用传统Date.Calendar和SimpleDateFormat等API ...

  7. Java8新特性(一)——Lambda表达式与函数式接口

    一.Java8新特性概述 1.Lambda 表达式 2. 函数式接口 3. 方法引用与构造器引用 4. Stream API 5. 接口中的默认方法与静态方法 6. 新时间日期 API 7. 其他新特 ...

  8. JAVA8新特性——接口定义增强

    JAVA9都要出来了,JAVA8新特性都没搞清楚,是不是有点掉队哦~ 接口定义增强 在JDK1.8以前,接口是定义的: 接口(英文:Interface),在JAVA编程语言中是一个抽象类型,是抽象方法 ...

  9. java8新特性学习:函数式接口

    本文概要 什么是函数式接口? 如何定义函数式接口? 常用的函数式接口 函数式接口语法注意事项 总结 1. 什么是函数式接口? 函数式接口其实本质上还是一个接口,但是它是一种特殊的接口:SAM类型的接口 ...

随机推荐

  1. poj-1511

    从1节点到所有节点的最短路和,加上所有节点返回1节点的最短路和,刚开始的方法时间复杂度有毒啊 其实只要把边全反向重装一次就好了哈哈哈 好了就是这样,套路了一个dijkstra+优先队列 #includ ...

  2. 线程的通信与协作:sleep、wait、notify、yield、join关系与区别

    一.sleep.join.yield.wait.notify.notifyAll 1.sleep() 使当前线程(即调用该方法的线程)暂停执行一段时间,让其他线程有机会继续执行,但它并不释放对象锁.也 ...

  3. Alpha阶段中间产物提交入口

    此作业要求参见:https://edu.cnblogs.com/campus/nenu/2019fall/homework/9865 git地址:https://e.coding.net/Eustia ...

  4. 面试官刁难:Java字符串可以引用传递吗?

    老读者都知道了,六年前,我从苏州回到洛阳,抱着一幅"海归"的心态,投了不少简历,也"约谈"了不少面试官,但仅有两三个令我感到满意.其中有一位叫老马,至今还活在我 ...

  5. redis集群数据迁移txt版

    ./redis-trib.rb create --replicas 1 192.168.112.33:8001 192.168.112.33:8002 192.168.112.33:8003 192. ...

  6. 机器学习-Pandas 知识点汇总(吐血整理)

    Pandas是一款适用很广的数据处理的组件,如果将来从事机械学习或者数据分析方面的工作,咱们估计70%的时间都是在跟这个框架打交道.那大家可能就有疑问了,心想这个破玩意儿值得花70%的时间吗?咱不是还 ...

  7. 「P5004」专心OI - 跳房子 解题报告

    题面 把\(N\)个无色格子排成一行,选若干个格子染成黑色,要求每个黑色格子之间至少间隔\(M\)个格子,求方案数 思路: 矩阵加速 根据题面,这一题似乎可以用递推 设第\(i\)个格子的编号为\(i ...

  8. 小小知识点(三十八)MPSK和MQAM调制的实现——利用IQ调制

    IQ调制的原理 (一)调制基本原理 (二)调制基本原理 利用IQ调制实现MPSK(QPSK 8PSK BPSK)和MQAM(16QAM 64QAM)调制     (一)利用IQ调制实现QPSK调制   ...

  9. 08_jquery里面的$(this)和this都什么时候用,有什么区别

    当你用的是jquery时,就用$(this),如果是JS,就用this $(this).html( $(this).html() + " BAM! "); 这个里的html()是J ...

  10. JVM之GC(一)

    Java较C而言,最大的区别在于内存管理.JVM设有无用内存空间自动回收复用机制,也就是我们所说的GC. 之前说过,栈是为线程.为函数的执行分配内存的地方,用完即“销毁”,这里留待以后做深入探讨:堆是 ...