浅谈java中静态方法的重写问题详解

时间:2022-12-24 10:13:04 

首先来看看以下程序将会打印出什么:


class Dog {
    public static void bark() {
        System.out.print("woof ");
    }
}

class Basenji extends Dog {
    public static void bark() { }
}

public class Bark {
    public static void main(String args[]) {
        Dog woofer = new Dog();
        Dog nipper = new Basenji();
        woofer.bark();
        nipper.bark();
    }
}

随意地看一看,好像该程序应该只打印一个woof。毕竟,Basenji扩展自Dog,并且它的bark方法定义为什么也不做。main方法调用了bark方法,第一次是在Dog类型的woofer上调用,第二次是在Basenji类型的nipper上调用。巴辛吉小鬣狗并不会叫唤,但是很显然,这一只会。如果你运行该程序,就会发现它打印的是woof woof。这只可怜的小家伙到底出什么问题了?

问题在于bark是一个静态方法,而对静态方法的调用不存在任何动态的分派机制[JLS 15.12.4.4]。当一个程序调用了一个静态方法时,要被调用的方法都是在编译时刻被选定的,而这种选定是基于修饰符的编译期类型而做出的,修饰符的编译期类型就是我们给出的方法调用表达式中圆点左边部分的名字。在本案中,两个方法调用的修饰符分别是变量woofer和nipper,它们都被声明为Dog类型。因为它们具有相同的编译期类型,所以编译器使得它们调用的是相同的方法:Dog.bark。这也就解释了为什么程序打印出woof woof。尽管nipper的运行期类型是Basenji,但是编译器只会考虑其编译器类型。

要订正这个程序,直接从两个bark方法定义中移除掉static修饰符即可。这样,Basenji中的bark方法将覆写而不是隐藏Dog中的bark方法,而该程序也将会打印出woof,而不是woof woof。通过覆写,你可以获得动态的分派;而通过隐藏,你却得不到这种特性。

标签:java,静态方法,重写
0
投稿

猜你喜欢

  • Java使用DOM4j实现读写XML文件的属性和元素

    2021-10-19 00:21:52
  • Java之常用类小结案例讲解

    2022-10-08 07:34:24
  • SpringCloud:feign对象传参和普通传参及遇到的坑解决

    2023-02-17 11:18:58
  • Android实现全局悬浮框

    2021-11-22 12:15:40
  • IDEA部署JavaWeb项目到Tomcat服务器的方法

    2023-11-02 23:21:22
  • Android实现读取NFC卡的编号

    2021-07-13 11:19:21
  • 巧用Spring中的@Order进行排序

    2023-07-13 05:53:48
  • Spring Data Jpa的四种查询方式详解

    2021-10-10 10:35:26
  • android RecyclerView实现条目Item拖拽排序与滑动删除

    2023-03-20 20:50:36
  • 基于android studio的layout的xml文件的创建方式

    2022-10-31 10:52:06
  • Java解决No enclosing instance of type PrintListFromTailToHead is accessible问题的两种方案

    2022-10-30 00:31:51
  • springboot调用支付宝第三方接口(沙箱环境)

    2023-11-25 06:12:08
  • Spring底层事务原理解析

    2021-11-25 05:40:29
  • C# 获取硬盘号,CPU信息,加密解密技术的步骤

    2023-04-23 10:37:50
  • 解析C#彩色图像灰度化算法的实现代码详解

    2022-01-26 07:34:55
  • IDEA GIT 忽略文件的最佳方式推荐

    2023-04-06 10:02:54
  • Spring中Bean的生命周期使用解析

    2021-09-06 23:06:54
  • 浅谈springBoot注解大全

    2023-11-09 15:02:56
  • 一文带你了解C#中的协变与逆变

    2022-08-06 22:31:21
  • C#判断一个字符串是否是数字或者含有某个数字的方法

    2022-05-07 14:38:17
  • asp之家 软件编程 m.aspxhome.com