Java 8:默认方法解析规则
随着Java 8中默认方法的引入,一个类现在可以从多个位置(例如另一个类或接口)继承相同的方法。 在这种情况下,可以使用以下规则来确定选择哪种方法:
- 类或超类方法声明始终优先于默认方法
- 否则,将使用具有最具体的默认提供接口的方法
- 最后,如果方法同样特定,则会出现编译器错误,并且您将被迫显式覆盖该方法并指定您的类应调用的方法
让我们看一些示例并应用这些规则。
范例1:
以下代码显示什么?
public interface A {default void name() {System.out.println("A");}
}public interface B {default void name() {System.out.println("B");}
}public class C implements A {@Overridepublic void name() {System.out.println("C");}
}public class D extends C implements A, B {public static void main(final String... args) {new D().name();}
}
答案 :C
这是因为,如规则1所述,超类C
的name()
方法声明优先于A
和B
的默认方法声明。
范例2:
以下代码显示什么?
public interface A {default void name() {System.out.println("A");}
}public interface B extends A {@Overridedefault void name() {System.out.println("B");}
}public class C implements A {}public class D extends C implements A, B {public static void main(final String... args) {new D().name();}
}
答案 :B
不同于前面的例子, C
不覆盖name()
但由于它实现A
,它具有从默认方法A
。 根据规则2,如果类或超类中没有方法,则选择最特定的默认提供接口。 因为B
扩展了A
,所以它更加具体,因此打印了“ B”。
范例3:
以下代码显示什么?
public interface A {default void name() {System.out.println("A");}
}public interface B {default void name() {System.out.println("B");}
}public class D implements A, B {public static void main(final String... args) {new D().name();}
}
答 :编译器错误! Duplicate default methods named name with the parameters () and () are inherited from the types B and A
在此示例中,没有更多特定的默认提供接口可供选择,因此编译器将引发错误。 要解决该错误,您需要显式覆盖D
的方法,并指定要D
使用的方法声明。 例如,如果要使用B
:
class D implements A, B {@Overridepublic void name() {B.super.name();}
}
范例4:
以下代码显示什么?
public interface A {default void name() {System.out.println("A");}
}public interface B extends A {}public interface C extends A {}public class D implements B, C {public static void main(final String... args) {new D().name();}
}
答 :A
子接口B
和C
并未覆盖该方法,因此实际上只有A
的方法可供选择。 附带说明一下,如果B
或C
(但不是全部)都覆盖了该方法,则将应用规则2。 顺便说一句,这是钻石问题 。
翻译自: https://www.javacodegeeks.com/2016/06/java-8-default-method-resolution-rules.html
Java 8:默认方法解析规则相关推荐
- java的默认值规则_Java 8:默认方法解析规则
java的默认值规则 随着Java 8中默认方法的引入,一个类现在可以从多个位置(例如另一个类或接口)继承相同的方法. 在这种情况下,可以使用以下规则来确定选择哪种方法: 类或超类方法声明始终优先于默 ...
- Java 8默认方法会破坏你的(用户的)代码
Java 8的默认方法试图尝试更进一步简化Java API.不幸的是,这一最近的语言扩展带来了一系列复杂的规则,但只有少部分Java开发者意识到这一点.这篇文章告诉你为什么引入默认方法会破坏你的(用户 ...
- java8 默认方法_如何不使用Java 8默认方法
java8 默认方法 警告:一旦阅读,您将无法看不到它 我在上一篇博客文章中讨论了默认方法的多重继承,以及它们在编译和运行时的行为. 这周,我将研究如何使用默认方法进行真正的继承,实际上,默认方法并非 ...
- Java 8默认方法可能会破坏您的(用户)代码
乍一看, 默认方法为Java虚拟机的指令集带来了一个很棒的新功能. 最后,库开发人员能够开发已建立的API,而不会对其用户代码造成不兼容性. 使用默认方法,当将新方法引入该接口时,任何实现库接口的用户 ...
- 如何不使用Java 8默认方法
警告:一旦阅读,您将无法看不到它 我在上一篇博客文章中讨论了默认方法的多重继承,以及它们在编译和运行时的行为. 这周,我将研究如何使用默认方法进行真正的继承,实际上,默认方法并不是为这种方法而设计的. ...
- java正则表示式方法解析与示例
文章目录 java.util.regex包介绍 正则表达式语法 实例及描述: 代码示例 1.Pattern.complie(String regex) 2.Pattern.matches(String ...
- 【Java 8】默认方法
本文参考书籍<Java 8实战>,陆明刚.劳佳 译,如有侵权,请联系删除! 默认方法简介 我们知道,实现接口的类必须为接口中定义的所有抽象方法提供一个实现,如果向接口中加入了新的方法,那 ...
- List元素互换,List元素转换下标,Java Collections.swap()方法实例解析
Java Collections.swap()方法解析 jdk源码: public static void swap(List<?> list, int i, int j) {// ins ...
- java 二义性_Java接口默认方法带来的问题分析【二义性问题】
本文实例分析了Java接口默认方法带来的问题.分享给大家供大家参考,具体如下: 一 点睛 Java 8中,如果一个类实现两个或多个接口,即"变相"的多继承,但是若其中两个接口都包含 ...
最新文章
- PHP随手记1--内置函数date
- 【Groovy】闭包 Closure ( 自定义闭包参数 | 自定义单个闭包参数 | 自定义多个闭包参数 | 闭包参数默认值指定 )
- webstorm 不识别.config文件_webstorm好用的十款插件
- centos恢复图形界面_centos图形界面的开启和关闭
- sqoop——将mysql数据库的数据表导入到hdfs上
- ASP.NET:页面保存为WORD出现的问题!
- python 高阶函数之 reduce
- java虚拟机06-内存分区/新生代、老年代
- mybatis3 中 @Provider 的使用方式
- 为Spring Cloud Ribbon配置请求重试(Camden.SR2+)
- Kubernetes之(五)快速部署应用
- [React] 尚硅谷 -- 学习笔记(七)
- 操作系统锁的实现方法有哪几种_Java并发之Monitor实现
- 阶段3 2.Spring_04.Spring的常用注解_3 用于创建的Component注解
- 开源组件分析工具OpenSCA教程
- Angel investor
- Android使用App Architecture打造最佳体验和高质量应用《一》
- 基于51单片机的体脂检测系统设计(51+oled+hx711+us100)
- Ubuntu包依赖损坏的解决unmet dependencies
- 阿里巴巴 OSS与AWS(亚马逊) S3 和腾讯云cos 存储服务 介绍篇