嗨喽~小伙伴们,早上好,中午好,晚上好呀,
之前有一个小伙伴给我发了一段代码,说是看不懂,这段代码是这样的:
public class Aha {
public static void main(String[] args) {
Care iCare = () -> System.out.println("Hahahahaha~");
iCare.care();
}
}
interface Care{
void care();
}
如果屏幕面前的你也不是很能够理解,那就听我细讲吧。
首先,在理解上述代码之前,我们需要了解一个概念-----函数式接口。
问:什么叫函数式接口?
所谓函数式接口,就是指只定义了一个抽象方法的接口。
比如如下的接口便是一个最简单的函数式接口:
interface Care{
void care();
}
如果你对jdk的源码有过研究的话,
会发现JDK中也提供了许多函数式接口,比如我们熟悉的 Runnable 接口和 Callable 接口:
细心的小伙伴会发现,上面两段源码中均对接口加上了一个注解:@FunctionalInterface ,顾名思义,这表示该接口会被设计成一个函数式接口,不符合规范的话,编译时会报错。
再比如线程池中的 Executor 接口:
那么问题来了,将接口设计成函数式接口有什么好处呢?
我们通过一个例子来领会它的妙处,首先,上一段简单的代码:
public class Haha {
public static void main(String[] args) {
ILike iLike = new Like();
iLike.like();
}
}
interface ILike{
void like();
}
//普通实现类
class Like implements ILike{
@Override
public void like() {
System.out.println("我是易果啥笔");
}
}
相信学过接口的小伙伴们能够很轻松地看懂上面这段代码。
现在我们深入地想一想,如果ILike这个接口仅仅是在Haha这个类中使用,那我们没必要新建一个外部Like实现类,一个很自然的想法便是将Like实现类设计成静态内部类:
public class Haha {
//静态内部类
static class Like implements ILike{
@Override
public void like() {
System.out.println("我是易果啥笔");
}
}
public static void main(String[] args) {
ILike iLike = new Like();
iLike.like();
}
}
}
interface ILike{
void like();
}
既然想到了设计成静态内部类,为何不干脆设计成局部内部类呢:
public class Haha {
public static void main(String[] args) {
ILike iLike = new Like();
iLike.like();
//局部内部类
class Like implements ILike{
@Override
public void like() {
System.out.println("我是易果啥笔");
}
}
}
}
interface ILike{
void like();
}
进一步,如果你学过匿名内部类的话,咱还可以把实现类的类名Like省略,简化成:
public class Haha {
public static void main(String[] args) {
ILike iLike = new ILike() {
@Override
public void like() {
System.out.println("我是易果啥笔");
}
}; //注意此处要有一个分号结尾
iLike.like();
}
}
interface ILike{
void like();
}
现在,我们来看核心代码:
ILike iLike = new ILike() {
@Override
public void like() {
System.out.println("我是易果啥笔");
}
};
上面这段代码,已经把实现接口的类的类名给省略了,我们想一想,还能不能省略点东西?
实际上,iLike前面已有ILike修饰,故后面的“new ILike”字样完全可以省略,不会产生歧义。
而且,重点来了!!!由于ILike本身是一个函数式接口,它只有一个抽象方法 like() ,所以上面的代码中完全可以把重写的like()方法中的“死代码”去掉而不会产生歧义,甚至花括号也可以去掉,直接写成:
ILike iLike = () System.out.println ( " 我是易果啥笔 " ) ;
当然,在 jdk8(或更高)规范中,需要我们加上一个小箭头“ -> ”:
ILike iLike = () -> System.out.println("我是易果啥笔");
到这,我们已经将一个复杂的代码块缩短成了最简单的一行代码,这种用“->”符号来编写的表达式,便称为匿名表达式,也叫Lambda表达式。从上述过程可以看出,Lambda表达式的优点在于能够使代码变得更为简洁。
注意,能够将代码缩短至一行是有一定条件的,下面的代码列举的应该包含绝大多数情况了:
//如果接口实现的语句不止一个,则必须加上花括号{},这与if,for,while语法类似:
ILike iLike = () -> {
System.out.println("我是易果啥笔");
System.out.println("我是易果啥笔2");
};
//如果接口含且仅含有一个参数(比如含有int a,这时可以省略括号和申明:int)
ILike iLike = a -> System.out.println("我是易果啥笔");
//如果接口含有多个参数(比如含有int a,String b,这时不能省略括号,但仍可以省略申明:int和String)
ILike iLike = (a,b) -> System.out.println("我是易果啥笔");
到这,我想小伙伴们应该就能够理解本文最开始给出的那段代码了,其实就是一个简单的Lambda表达式而已:
public class Aha {
public static void main(String[] args) {
Care iCare = () -> System.out.println("Hahahahaha~");
iCare.care();
}
}
interface Care{
void care();
}
事实上,Lambda表达式的应用远不止这些,有兴趣的小伙伴可以去查询更多的资料了解Lambda表达式的其他应用。
那么今天的知识就分享到这里啦,喜欢的小伙伴们点个赞鼓励支持一下吧~