Java 函数式接口 FunctionInterface 解析

    函数式编程是 java 8 的新特性,lambda 表达式中用到了很多函数式接口。比如 Runnable 接口 :

public class Mytest {


	public static void main(String[] args) {
		new Thread( ()-> System.out.println( Thread.currentThread() +"  is running ...") 
                  ).start();
	}
}

    下面是 Runnable 接口的源代码。我们可以看到 @FunctionalInterface 注解修饰了 Runnable 接口。

@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 注解的源码。

第一段表示,该注解修饰的接口是函数式接口。

第二段表示,一个函数式接口有且仅有一个抽象方法。1.接口中的default 实例方法 不是抽象方法。     2. java.lang.Object 中的方法 在接口中重写,也不能算作 抽象方法。因为该接口的实现类中都会有 java.lang.Object 的实例方法。

第三段表示,可以通过 lambda 表达式、方法引用、构造方法引用 来创建 函数式接口 的实例。

第四段表示。1.该注解无法用于修饰 注解(@interface)、enum(枚举)、class(普通java类)。

2.该注解修饰的接口,必须满足函数式接口的要求。(具体要求在第二段)。

第五段表示,不管接口声明上是否有@FunctionInterface 注解,编译器都会自动将满足条件的接口作为函数式接口。

/**
 * An informative annotation type used to indicate that an interface
 * type declaration is intended to be a <i>functional interface</i> as
 * defined by the Java Language Specification.
 *
 * Conceptually, a functional interface has exactly one abstract
 * method.  Since {@linkplain java.lang.reflect.Method#isDefault()
 * default methods} have an implementation, they are not abstract.  If
 * an interface declares an abstract method overriding one of the
 * public methods of {@code java.lang.Object}, that also does
 * <em>not</em> count toward the interface's abstract method count
 * since any implementation of the interface will have an
 * implementation from {@code java.lang.Object} or elsewhere.
 *
 * <p>Note that instances of functional interfaces can be created with
 * lambda expressions, method references, or constructor references.
 *
 * <p>If a type is annotated with this annotation type, compilers are
 * required to generate an error message unless:
 *
 * <ul>
 * <li> The type is an interface type and not an annotation type, enum, or class.
 * <li> The annotated type satisfies the requirements of a functional interface.
 * </ul>
 *
 * <p>However, the compiler will treat any interface meeting the
 * definition of a functional interface as a functional interface
 * regardless of whether or not a {@code FunctionalInterface}
 * annotation is present on the interface declaration.
 *
 * @jls 4.3.2. The Class Object
 * @jls 9.8 Functional Interfaces
 * @jls 9.4.3 Interface Method Body
 * @since 1.8
 */
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface FunctionalInterface {}

接下来,我们再来看看 JDK 提供的一些常用函数式接口。java.util.function 包下面有一些 Stream 流操作用到的函数式接口。

       下面我们利用注解@FunctionInterface 来实现一个自定义的函数式接口

//@FunctionalInterface   //可以省略
public interface MySayInterface {
	void say(String content);
}

       我们再写一段测试代码。

public class Mytest {


	public static void main(String[] args) {
/*		new Thread( ()-> System.out.println( Thread.currentThread() +"  is running ...")  ).start();

 		MySayInterface  sayInterface = new MySayInterface() {
			@Override
			public void say(String content) {
				System.out.println( content );
			}
		}; */
		MySayInterface  sayInterface =(content )-> System.out.println( content );
		sayInterface.say(" functional interface ");

	}
}

    我们来看看运行效果。控制台成功输出了“functional interface”

Connected to the target VM, address: '127.0.0.1:41985', transport: 'socket'
Disconnected from the target VM, address: '127.0.0.1:41985', transport: 'socket'
 functional interface 

Process finished with exit code 0

 

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java中,所有的函数式接口都被定义在`java.util.function`包下。下面列出了常见的函数式接口及其用途: 1. Supplier<T>:不接收参数,返回一个T类型的结果。用于提供一个T类型的值,例如生成随机数等操作。 2. Consumer<T>:接收一个T类型的参数,不返回结果。用于对一个T类型的值进行消费,例如打印输出等操作。 3. Function<T, R>:接收一个T类型的参数,返回一个R类型的结果。用于对一个T类型的值进行转换,例如将字符串转换为整数等操作。 4. Predicate<T>:接收一个T类型的参数,返回一个boolean类型的结果。用于判断一个T类型的值是否满足某个条件,例如判断一个数是否为偶数等操作。 5. UnaryOperator<T>:接收一个T类型的参数,返回一个T类型的结果。是Function<T, T>的简化版,用于对一个T类型的值进行转换。 6. BiFunction<T, U, R>:接收两个参数,一个T类型的参数和一个U类型的参数,返回一个R类型的结果。用于对两个值进行转换,例如将两个数相加等操作。 7. BiPredicate<T, U>:接收两个参数,一个T类型的参数和一个U类型的参数,返回一个boolean类型的结果。用于判断两个值是否满足某个条件。 8. BinaryOperator<T>:接收两个T类型的参数,返回一个T类型的结果。是BiFunction<T, T, T>的简化版,用于对两个T类型的值进行转换。 此外,还有一些其他的函数式接口,如`Runnable`、`Comparator`等,它们也都被定义在`java.util.function`包下。这些函数式接口Java 8中被引入,可以方便地使用Lambda表达式和方法引用来实现函数式编程。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值