Java中final修饰的方法是否可以被重写示例详解

 更新时间:2020年11月04日 10:20:33   作者:卷卷子  
这篇文章主要给大家介绍了关于Java中final修饰的方法是否可以被重写的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

这是一次阿里面试里被问到的题目,在我的印象中,final修饰的方法是不能被子类重写的。如果在子类中重写final修饰的方法,在编译阶段就会提示Error。但是回答的时候还是有点心虚的,因为final变量就可以用反射的方法进行修改,我也不太确定是否有类似的机制可以绕过编译器的限制。于是面试之后特地上网搜了下这个问题,这里简单记录一下。

首先说一下结论:没有办法能够做到重写一个final修饰的方法,但是有其他的方法可以接近在子类中重新实现final方法并在运行时的动态绑定的效果。

这里需要用到一个aop框架叫aspectj,它和spring aop都是比较常用的aop框架。区别是spring aop是基于动态代理的,而aspectj有独立的编译器可以实现静态代理。关于aspectj的安装配置网上有很多文章了,这里就不再赘述,直接快进到例子。

首先定义一个SuperClass并在其中定义一个final方法。

SuperClass.java

public class SuperClass {

 public final void doSomething() {
  System.out.println("super class do something");
 }

 public static void main(String[] args) {
  SuperClass instance = new SubClass(); //此处是父类引用和子类对象
  instance.doSomething();
 }

}

SubClass.java

public class SubClass extends SuperClass {

 //doSomething是final方法,无法被重写

}

super class do something

Process finished with exit code 0

运行main方法,SubClass继承了doSomething方法,但是不能重写,所以通常情况下调用的一定是SuperClass的doSomething方法。

在SubClass中实现“重写”的doSomething方法

SubClass.java

public class SubClass extends SuperClass {

 //doSomething是final方法,无法被重写
 //子类只能在另一个函数中实现重写的逻辑
 protected void overrideDoSomething() {
  System.out.println("sub class do something");
 }

}

利用环绕通知修改实际调用的方法

DoSomethingAspect.aj

public aspect DoSomethingAsepct {
 // 环绕通知    匹配SuperClass类的doSomething方法
 void around() : execution(* SuperClass.doSomething()) {
  if (thisJoinPoint.getThis() instanceof SubClass) {
   //调用子类方法
   ((SubClass)thisJoinPoint.getThis()).overrideDoSomething();
  } else {
   //调用原方法
   proceed();
  }
 }

}

运行结果

sub class do something

Process finished with exit code 0

可以看到,调用SubClass的doSomething方法时实际调用的是SubClass类的overrideDoSomething方法,而如果是SuperClass对象的话调用的又是SuperClass里的doSomething方法。根据实际的类型决定调用的方法,就比较接近动态绑定的机制了。而仅从调用的代码来看和子类重写方法(虽然实际是final)的效果是一样的。

总结

到此这篇关于Java中final修饰的方法是否可以被重写的文章就介绍到这了,更多相关Java中final修饰的方法被重写内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • SpringBoot Maven项目中Model间的最佳继承设计详解

    SpringBoot Maven项目中Model间的最佳继承设计详解

    这篇文章主要为大家详细介绍了SpringBoot中一个优秀Maven项目的各Model间最佳继承设计的相关知识,文中的示例代码讲解详细,感兴趣的小伙伴可以了解下
    2024-01-01
  • 教你怎么用Java操作Redis

    教你怎么用Java操作Redis

    今天带大家来学习怎么用Java操作Redis,文中有非常详细的介绍,对正在学习java的小伙伴们有很好的帮助,建议有redis基础并熟悉redis的基本数据类型命令的小伙伴学习,需要的朋友可以参考下
    2021-05-05
  • SpringBoot实现微信及QQ绑定登录的示例代码

    SpringBoot实现微信及QQ绑定登录的示例代码

    本文主要介绍了SpringBoot实现微信及QQ绑定登录的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-07-07
  • 轻松掌握Java代理模式

    轻松掌握Java代理模式

    这篇文章主要帮助大家轻松掌握Java代理模式,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-09-09
  • 如何解决springboot读取配置文件的中文乱码问题

    如何解决springboot读取配置文件的中文乱码问题

    本篇文章主要介绍了如何解决springboot读取配置文件的中文乱码问题,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看
    2018-05-05
  • Java 运算符 动力节点Java学院整理

    Java 运算符 动力节点Java学院整理

    这篇文章主要介绍了Java 运算符 动力节点Java学院整理,需要的朋友可以参考下
    2017-04-04
  • Jenkin邮件收发实现原理及过程详解

    Jenkin邮件收发实现原理及过程详解

    这篇文章主要介绍了Jenkin邮件收发实现原理及过程详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-09-09
  • Springboot深入讲解nocos的整合与使用

    Springboot深入讲解nocos的整合与使用

    Nacos 是阿里巴巴推出来的一个新开源项目,这是一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台,在项目开发过程中,我们经常使用nacos作为配置中心和注册中心。本文章我们就从代码层面研究下springboot是如何整合nacos使用的
    2022-07-07
  • 使用多个servlet时Spring security需要指明路由匹配策略问题

    使用多个servlet时Spring security需要指明路由匹配策略问题

    这篇文章主要介绍了使用多个servlet时Spring security需要指明路由匹配策略问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-08-08
  • Java基础类之ArrayUtils工具类详解

    Java基础类之ArrayUtils工具类详解

    这篇文章主要介绍了java.ArrayDeque类使用方法,java.ArrayDeque类提供了可调整大小的阵列,并实现了Deque接口,感兴趣的小伙伴们可以参考一下
    2021-09-09

最新评论