在JDK 1.8之前,default关键字用来标记switch语句中的默认分支。表示当不匹配任何case的时候,就会执行default代码块。

	String ss = "123456789";
	switch (ss) {
	    case "123":
	        break;
	    case "456":
	        break;
	    case "789":
	        break;
	    default:
	        System.out.println("123456789");
	}

JDK 1.8 引入很多新的特性,其中有lambda表达式,default方法,新的Date API等。在1.8之前,要在接口中引入新的方法,就必须打破现有的实现。而且 1.8 新引入的Lambda表达式,有明显的局限性,他们不能被重写的类实现扩展的接口,所有就有了default方法(Virtual extension methods)。

Default方法是指,在接口内部包含了一些默认的方法实现(也就是接口中可以包含方法体,这打破了Java之前版本对接口的语法限制),从而使得接口在进行扩展的时候,不会破坏与接口相关的实现类代码,例如:

public interface A {

    void method2();

    default void method1(){
        System.out.println("run method1");
    }
}

class impl implements A{

    @Override
    public void method2() {
        System.out.println("run method2");
    }

    public static void main(String[] args) {
        new impl().method1();
        new impl().method2();
    }
}

在这里,default方法,在接口中必须要有方法体,不然就会报错。



上面是简单的default方法使用,让我们来看看下面几种情况,更详细的理清default方法的使用。

1、

interface A {
    default void m() {
        System.out.println("123");
    }
}

interface B extends A {

}

interface C extends A {

}

class D implements B, C {

}

在这个例子中,尽管D继承m()从B和C,当我们构建接口提供了一个默认的m()方法中,我们看到的只有一个m() D实现了A中的m()。

interface A {
    default void m() {
        System.out.println("123");
    }
}

interface B extends A {
    default void m() {
        System.out.println("1234");
    }
}

interface C extends A {
    default void m() {
        System.out.println("12345");
    }
}

class D implements B, C {

}

在这种情况下,D中m()继承会暧昧(因为最具体的设置默认提供接口包含B和C)。在编译时D会被拒绝,除非D实现了m()。

2、

在下面的例子中,m()在D中必须实现abstract 方法,因为在C中的抽象声明优先于默认,不然也会报错。

interface A {
    default void m() {
        System.out.println("123");
    }
}

abstract class C {
    abstract void m();
}

class D extends C implements A {

}

3、

B的声明没有移除a的默认值 , B是相同的没声明m()。

interface A {
    default void m() {
        System.out.println("123");
    }
}

interface B extends A {
    void m();
}

4

当C同时实现了A,B 且A,B有不同的default 方法,方法名相同时,使用通过A.super.m() 来实现,不然编译的时候会产生错误,因为编译期不知道选择哪一个。

interface A {
    default void m() {
        System.out.println("123");
    }
}

interface B {
    default void m() {
        System.out.println("456");
    }
}

class C implements A, B {
    public void m() {
        A.super.m();
    }
}

class D implements A {
    public void m() {
        System.out.println("Calling m");
        A.super.m();
    }
}

上面是一些关于default使用中需要注意的一些,还有其他一些注意的,没有一一罗列,因为博主也是慢慢学习过程。如果有错误,也请大家不要吝啬,指点一二。

参考文献: Interface evolution via virtual extension methods