1 Java8接口新特性
接口改动一下就要修改对应的实现类,为了兼容老接口,Java8新增了默认方法和静态方法;
对于已经发布的版本,是没法在给接口添加新方法的同时不影响已有的实现
1)静态方法可以直接调用,不能被重写
2)默认方法需要通过实现类,重写后实例化后调用
一个例子,演示默认方法、静态方法和实现类中对它们的重写,抽象方法doSomthing()就不赘述:
//一个有多个默认方法和静态方法的接口CommonInterface
public interface CommonInterface {
//抽象方法
public void doSomthing();
//默认方法
default void defaultMehtod() {
System.out.println("CommonInterface's default method is running...");
}
//默认方法可以有多个
default void anotherDefaultMehtod() {
System.out.println("CommonInterface's second default method is running...");
}
//静态方法
static void staticMethod() {
System.out.println("CommonInterface's static method is running...");
}
//静态方法也可以有多个
static void anotherStaticMethod() {
System.out.println("CommonInterface's second static method is running...");
}
}
// 一个跟上边一模一样的接口CommonInterface1
public interface CommonInterface1 {
//抽象方法
public void doSomthing();
//默认方法
default void defaultMehtod() {
System.out.println("CommonInterface1's default method is running...");
}
//默认方法可以有多个
default void anotherDefaultMehtod() {
System.out.println("CommonInterface1's second default method is running...");
}
//静态方法
static void staticMethod() {
System.out.println("CommonInterface1's static method is running...");
}
//静态方法也可以有多个
static void anotherStaticMethod() {
System.out.println("CommonInterface1's second static method is running...");
}
}
实现类在尝试重写静态方法时报错,可见静态方法不允许重写:
public class CommonInterfaceImpl implements CommonInterface, CommonInterface1 {
@Override
public void doSomthing() {
System.out.println("CommonInterfaceImpl.doSomthing(): 我们来学习Java8新特性吧!");
}
@Override
public void defaultMehtod() {
System.out.println("CommonInterfaceImpl.defaultMehtod()-------------start");
CommonInterface.super.defaultMehtod();
CommonInterface1.super.defaultMehtod();
System.out.println("CommonInterfaceImpl.defaultMehtod()-------------end");
}
@Override
public void anotherDefaultMehtod() {
System.out.println("CommonInterfaceImpl.anotherDefaultMehtod()-------------start");
CommonInterface.super.anotherDefaultMehtod();
CommonInterface1.super.anotherDefaultMehtod();
System.out.println("CommonInterfaceImpl.anotherDefaultMehtod()-------------end");
}
}
客户端调用:
public class Client {
public static void main(String[] args) {
//默认方法 和 抽象方法需实现类实例化后调用
CommonInterface commonInterface = new CommonInterfaceImpl();
//抽象方法重写后调用
commonInterface.doSomthing();
//默认方法重写后调用
commonInterface.defaultMehtod();
commonInterface.anotherDefaultMehtod();
}
结果:
CommonInterface's static method is running...
CommonInterface's second static method is running...
CommonInterface1's static method is running...
CommonInterface1's second static method is running...
CommonInterfaceImpl.doSomthing(): 我们来学习Java8新特性吧!
CommonInterfaceImpl.defaultMehtod()-------------start
CommonInterface's default method is running...
CommonInterface1's default method is running...
CommonInterfaceImpl.defaultMehtod()-------------end
CommonInterfaceImpl.anotherDefaultMehtod()-------------start
CommonInterface's second default method is running...
CommonInterface1's second default method is running...
CommonInterfaceImpl.anotherDefaultMehtod()-------------end
2 函数式接口 Functional Interface
函数式接口(Functional Interface)是只有一个抽象方法的接口。
- 函数式接口中的抽象函数就是为了支持 lambda表达式;
- 函数式接口可以被隐式转换为lambda表达式;
- 为确保函数式接口符合语法,可以添加@FunctionalInterface注解;
@FunctionalInterface
public interface FuncInterface {
//只有一个抽象方法
public void reference();
//还可以有其他方法
//interface default method
default void defaultMehtod() {
System.out.println("This is a default method~");
}
//interface second default method
default void anotherDefaultMehtod() {
System.out.println("This is the second default method~");
}
//interface static method
static void staticMethod() {
System.out.println("This is a static method~");
}
//interface second static method
default void anotherStaticMethod() {
System.out.println("This is the second static method~");
}
}
3 java.util.function包
Java 8添加一个新的包"java.util.function",通常用于lambda表达式和方法引用,包下有很多通用接口:
大致可以分为这几类:
3.1 消费型接口
Consumer 有一个accept(T t) 方法接受一个入参没有返回,只要符合这个格式的参数,无需再写函数式接口,可以直接写lambda表达式:
方法:
/**
* buy方法有个Consumer<Integer>的入参
* @param money
* @param consumer
*/
public static void buy(Integer money, Consumer<Integer> consumer) {
consumer.accept(money);
}
客户端调用:
public static void main(String[] args) {
//消费型:第二个参数为实现了Consumer<T>接口accept(T t)方法的lambda表达式
buy(1000, money -> System.out.println("消费型-->我买面包花了:" + money + "元"));
}
结果:
消费型-->我买面包花了:1000元
3.2 供给型接口
Supplier 有一个get()方法无入参一个返回:
方法:
/**
* factory方法有个Supplier<Integer>的入参
* @param supplier
* @return
*/
public static String factory(Supplier<String> supplier) {
return supplier.get();
}
客户端调用:
public static void main(String[] args) {
//供给型:参数为实现了Supplier<Integer>接口get()方法的lambda表达式
String phone = factory(() -> {return "Apple8";});
System.out.println("供给型-->富士康生产的有名的手机是:" + phone);
}
结果:
供给型-->富士康生产的有名的手机是:Apple8
3.3 函数型接口
Function接口有一个apply(T t)方法接受入参有一个返回:
方法:
/**
* convert方法有个Function<String, Integer>的入参
* @param str
* @param function
* @return
*/
public static Integer convert(String str, Function<String, Integer> function) {
return function.apply(str);
}
客户端调用:
public static void main(String[] args) {
//函数型:参数为实现了Function<String, Integer>接口apply(T t)方法的lambda表达式
Integer num = convert("666", x -> Integer.parseInt(x));
System.out.println("函数型-->字符型666被转换成了数字: "+ num);
}
结果:
函数型-->字符型666被转换成了数字: 666
3.4 断言型接口
Predicate 有一个test(T t)方法有一个入参并返回一个boolean:
方法:
/**
* isNoble方法有个Predicate<String>的入参
*
* @param name
* @param predicate
* @return
*/
public static String isNoble(String name, Predicate<String> predicate) {
if (predicate.test(name))
return "贵族";
return "平民";
}
客户端调用:
public static void main(String[] args) {
//断言型:参数为实现了Predicate<String>接口test(T t)方法的lambda表达式
String na = "尼古拉斯赵四";
String noble = isNoble(na, (name) -> !"".equals(name) && name.contains("尼古拉斯"));
System.out.println("断言型-->从你的名字就可以看出你是个:" + noble);
}
结果:
断言型-->从你的名字就可以看出你是个:贵族
涉及代码:–>GitHub
参考文献:
[ 1 ]Java8函数式编程/(英)Richard Warburton著;王群锋译。–北京:人民邮电出版社,2015-03-01.
[ 2 ] http://www.importnew.com/26080.html
[ 3 ] http://java8.in/java-8-lambda-expression/
[ 4 ] https://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html#approach6
[ 5 ] https://winterbe.com/posts/2014/03/16/java-8-tutorial/