在上一篇《深入理解Java双冒号(::)运算符的使用》的结尾,讲到了Functionl Interface。
Functionl Interface:函数式接口(或称功能接口),它是只包含一个抽象方法的接口,它们只能显示一个功能。从Java 8开始,lambda表达式可以用来表示函数式接口的实例。函数接口可以有任意数量的默认方法。例如:Runnable、ActionListener和Comparable都是功能接口。
Jdk8中Runnable类的源码:
package java.lang;
/**
* @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();
}
这里需要特别注意的是Runnable接口上的@FunctionalInterface注解,加了这个注解,就表示该接口为函数式接口!
创建线程
在Java 8之前创建线程常见的方法是:创建匿名内部类实例或实现Runnable接口
public class ThreadDemo {
public static void main(String[] args){
//方法一:
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("通过内部匿名类实例创建一个线程!");
}
}).start();
//方法二:
MyThread thread = new MyThread();
thread.run();
}
}
class MyThread implements Runnable{
@Override
public void run() {
System.out.println("通过implements Runnable创建一个线程!");
}
}
运行结果:
通过内部匿名类实例创建一个线程!
通过implements Runnable创建一个线程!
Java 8之后,可以通过Lambda表达式(函数式接口)来实现创建一个线程:
new Thread(()->
{System.out.println("通过函数式接口创建一个线程!");}).start();
@FunctionalInterface Annotation
@FunctionalInterface注解用于确保函数接口不能有多个抽象方法。如果存在多个抽象方法,编译器将标记“unexpected@functionalinterface annotation”消息。但是,不强制使用此注释。
/**
* @author zhoufy
* @date 2019年2月28日 下午6:45:36
*/
public class Test {
@FunctionalInterface
interface Square {
int calculate(int x);
}
public static void main(String args[]) {
int a = 2;
// lambda expression to define the calculate method
Square s = (int x) -> x * x;
// parameter passed and return type must be
// same as defined in the prototype
int result = s.calculate(a);
System.out.println(result);
}
}
运行结果:
4
/**
* @author zhoufy
* @date 2019年2月28日 下午6:45:36
*/
public class Test {
interface Square {
int calculate(int x);
}
public static void main(String args[]) {
int a = 2;
// lambda expression to define the calculate method
Square s = (int x) -> x * x;
// parameter passed and return type must be
// same as defined in the prototype
int result = s.calculate(a);
System.out.println(result);
}
}
运行结果:
4
从上面两个示例可以看出来,@FunctionalInterface注解并不是必须加的!