default关键字的用法

default关键字的用法

前言

在学习集合时,深入到Iterable发现了这个default关键字

default void forEach(Consumer<? super T> action) {
    Objects.requireNonNull(action);
    for (T t : this) {
        action.accept(t);
    }
}

理论探究

default关键字在java中,目前有两个地方能用到

一是switch中的default:switch在匹配时,最后来一个default,防止因为没有匹配到结果,使后续程序异常。

二是接口中的default:从JDK8开始,接口中可以添加默认方法了,default就是用来修饰这个方法的。

代码实现

switch中的default

switch执行过程中,如果没有符合条件的case,就执行default下的代码块,这里的default并不是必要的,也可以不写,程序也会正常执行,只是,如果后续有业务用到这个switch的值,而代码中又没有匹配到相关结果,可能就会出问题。

package com.cdh.keyDefault;
/**
* @author chudonghai
* @ClassName SwitchDefaultDemo
* @Description switch中的default
*/

public class SwitchDefaultDemo {

    public static void main(String[] args) {
        defaultTest();
    }

    /*
     * 判断是否匹配:不匹配
     *       输出:ERROR!
     */
    private static void defaultTest() {
        String string = new String("helloworld");
        switch (string) {
        case "hello":
            System.out.println("hello case");
            break;
        case "world":
        	System.out.println("world case");
        	break;

        default:
            System.out.println("ERROR!");
            break;
        }
    }
}

接口中的default

重点来了,这是本篇的重头戏,这也是JDK8加入的新特性。

接口有很多的好处,诸如多实现,低耦合,对外提供规则等;

但缺点也会在某些场景中凸显出来,当修改接口时,需要修改全部实现该接口的类。

例如:JDK8,在Iterable中,新增了一个新方法forEach,这里就出现一个问题。

目前,JDK8之前的版本,集合框架都没有foreach方法,如何对已发布的接口进行修改而又不影响当前实现类的正常运行,这在生产中是一个很大的问题。对此,我们一般能想到的解决办法是在JDK里给相关的接口添加新的方法及实现。然而,对于已经发布的版本,无法同时满足既给接口添加新方法又不影响已有的实现,如果一味强行在每个类中进行添加,且不说风险问题,单是这个工作量就足以让程序员们彻夜不休,如果项目庞大,这个工作量更是让人生畏,所以,之前都是尽量避免这种改接口的问题。为此JDK8引入了默认方法default。它同时满足了既给接口添加新方法又不影响已有的实现这个大难题。

好了扯了这一堆希望你能听懂,不懂也没关系,咱看看代码:

接口中default的用法(代码实现)
1.直接调用父接口实现
/**
* @author chudonghai
* @InterfaceName Interface1
* @Description 创建接口Interface1,并在接口中定义默认方法helloworld
*/
public interface Interface1 {
	default void helloworld() {
		System.out.println("this is JDK8 Interface1");
	}
}
/**
* @author chudonghai
* @ClassName MyImpl1
* @Description MyImpl1:接口1的实现类,调用接口中的默认方法
*/
public class MyImpl1 implements Interface1{
	
	public static void main(String[] args) {
		MyImpl1 mi = new MyImpl1();
		mi.helloworld();
	}
}

此时,接口-类关系图,如下:

结果如下:

this is JDK8 Interface1
2.继承多个接口
/**
* @author chudonghai
* @ClassName Interface2
* @Description 创建接口Interface2,并在接口中定义默认方法helloworld
*/
public interface Interface2 {
	default void helloworld() {
		System.out.println("this is JDK8 Interface2");
	}
}
/**
* @author chudonghai
* @ClassName MyImpl1
* @Description MyImpl1:接口1,接口2的实现类,调用接口中的默认方法
*/
public class MyImpl1 implements Interface1,Interface2{
	
	public static void main(String[] args) {
		MyImpl1 mi = new MyImpl1();
		mi.helloworld();
	}
}

此时发现实现类MyImpl1会报错:Duplicate default methods named helloworld...

翻译过来就是,名为helloworld的默认方法重复啦,,,

也就是说,现在程序不知道你到底是要运行哪个接口中的helloworld方法,怎么办???

下面提供两种解决办法:

方法一:直接指定这个方法属于哪个接口。

方法二:直接进行重写此方法。

/**
* @author chudonghai
* @ClassName MyImpl1
* @Description MyImpl1:接口1,接口2的实现类,调用接口中的默认方法
*/
public class MyImpl1 implements Interface1,Interface2{
	
	public static void main(String[] args) {
		MyImpl1 mi = new MyImpl1();
		mi.helloworld();
	}

//	/**
//	 * 方法一:直接指定这个方法属于哪个接口
//	 * */
//	@Override
//	public void helloworld() {
//		Interface1.super.helloworld();
//	}
    
	/**
	 * 方法二:直接重写此方法
	 * */
	@Override
	public void helloworld() {
		System.out.println("Here is MyImpl1");
	}
}

此时,接口-类关系图,如下:

方法一结果如下:

this is JDK8 Interface1

方法二结果如下:

Here is MyImpl1

3.类优先于接口
/**
* @author chudonghai
* @ClassName MyImpl2
* @Description MyImpl2继承MyImpl1(方法helloworld已重写)实现Interface2
*/
public class MyImpl2 extends MyImpl1 implements Interface2{
	
	/**
	 * 此时,MyImpl2中调用的helloWorld到底是MyImpl1中的还是Interface2中的?
	 * 答案:是MyImpl1中的
	 * 原因:类优先于接口。从结果来看确是如此
	 * */
	public static void main(String[] args) {
		MyImpl2 mi = new MyImpl2();
		mi.helloworld();
	}
}

此时,接口-类关系图,如下:

结果如下:

Here is MyImpl1

总结

default的使用场景:

  1. switch中的default:switch在匹配时,最后添加default,防止因为没有匹配到结果,使后续程序异常。
  2. 接口中的default:从JDK8开始,接口中可以添加默认方法了,default就是用来修饰这个方法的。

​ ①直接调用父接口实现

​ ②继承多个接口

​ ③类优先于接口

=======================================================================================

善于学习,善于总结

=======================================================================================

posted @ 2019-09-25 23:09  向南风  阅读(1530)  评论(0编辑  收藏  举报