匿名内部类
匿名内部类主要是针对继承(类继承、抽象类继承、接口实现)这一概念而形成的一种简化定义,首先我们来观察如下一段代码。
范例:观察传统实现方式的问题
interface IMessage {
public void send(String msg);
}
class MessageImpl implements IMessage{
public void send(String msg){
System.out.println(msg);
}
}
class TestDemo{
public static void main(String[] args) {
IMessage msg = new MessageImpl();
msg.send("www.mldn.cn");
}
}
// 执行结果: www.mldn.cn
如果现在定义的 MessageImpl 子类只使用唯一的一次,那么是否还有必要将其定义为一个单独的类呢,这样就可以利用匿名内部类的形式来简化当前的类定义。
范例:匿名内部类
interface IMessage {
public void send(String msg);
}
class TestDemo{
public static void main(String[] args) {
IMessage msg = new IMessage() {
@Override
public void send(String msg) {
System.out.println(msg);
}
};
msg.send("www.mldn.cn");
}
}
// 执行结果: www.mldn.cn
使用匿名内部类可以针对于只在一个地方上使用的接口或者抽象类的子类进行简单的定义,从而减少项目中 *.java 文件的出现,但是依然会有 *.class 文件出现。
Lambda表达式
Lambda表达式的背景:解决匿名内部类代码过于冗余的问题,另外为了方便Lambda表达式的使用,Java从JDK 1.8 开始内方法中的内部类可以在不加final的情况下直接访问方法的参数。
Lambda是一种函数式编程(最早的函数式编程“haskell”),Java 从 JDK1.8 开始引入之后,整体的开发结构上就发生了改变。
传统的匿名内部类中最核心的部分只有一行语句”System.out.println(msg);“,但是由于Java之中的面向对象结构的严苛要求,所以不得不编写许多与之辅助的,并且和实际开发完全没有关系的结构。
范例:使用Lambda解决当前的问题
interface IMessage {
public void send(String msg);
}
class TestDemo{
public static void main(String[] args) {
IMessage msg =(str)->{
System.out.println(str);
};
msg.send("www.mldn.cn");
}
}
// 执行结果:www.mldn.cn
与匿名内部类相比,使用Lambda表达式代码整体会简洁许多,在 Java 中使用Lambda表达式基本上采用的语法如下:
编写多行语句: | (参数,参数,...) -> { 方法体; } |
---|---|
编写单行返回语句: | (参数,参数,...) -> 计算表达式; |
在使用函数式编程的时候有一个重要的前提:一个接口只允许出现有一个抽象方法,如果接口中要想有其他的方法,只能够是static方法或者是default方法,于是为了防止有一下开发者在使用Lambda表达式的接口上定义更多的抽象方法,所以Java提供有一个新的注解“ @FunctionalInterface”(函数式接口)。
使用Lambda操作目的是改善匿名内部类的使用,同时使用简化的语法形式进行方法覆写的实现。
如果对于一个函数式接口中的方法功能非常简单,只是进行简单的表达式计算并且返回结果,那么可以单行编写。
范例:编写简单的函数式接口
@FunctionalInterface
interface IMath{
public int add(int a,int b);
}
public class test {
public static void main(String[] args) {
IMath ma=(a,b)->a+b;
System.out.println(ma.add(10,30));
}
}
//执行结果:40
Lambda 从诞生开始就替代匿名内部类的实现,但是也要求有接口的支持。