default关键字的用法

Posted chudonghai

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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就是用来修饰这个方法的。

? ①直接调用父接口实现

? ②继承多个接口

? ③类优先于接口

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

善于学习,善于总结

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

以上是关于default关键字的用法的主要内容,如果未能解决你的问题,请参考以下文章

Java接口的default关键字用法解释

c++ default override delete关键字

sql关键字作为jpa实体列名的用法

类型转换关键字explicit与implicit的用法

datetime default curdate怎么用

c语言中case是啥意思