美文网首页
Java中final修饰的方法是否可以被重写示例详解

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

作者: 平凡的柚子 | 来源:发表于2021-01-16 17:08 被阅读0次

这是一次阿里面试里被问到的题目,在我的印象中,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)的效果是一样的。


最新2020整理收集的一些高频面试题(都整理成文档),有很多干货,包含mysql,netty,spring,线程,spring cloud、jvm、源码、算法等详细讲解,也有详细的学习规划图,面试题整理等,需要获取这些内容的朋友请加Q君样:11604713672

相关文章

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

    这是一次阿里面试里被问到的题目,在我的印象中,final修饰的方法是不能被子类重写的。如果在子类中重写final修...

  • Java中static和final的区别

    1.final可以修饰变量、方法及类:final修饰的类,不能被继承final修饰的方法,不能被重写final修饰...

  • final

    1、final修饰的类 final修饰的类不能被继承 2、final修饰的方法 final修饰的方法不可以被重写 ...

  • final关键字

    final可以修饰类、方法、属性和变量final修饰类,则该类不能被继承final修饰方法,方法不能被重写fina...

  • final修饰的变量

    final的作用 被final修饰的类不可以被继承 被final修饰的方法不可以被重写 被final修饰的变量不可...

  • final关键字

    final:可以修饰 类,方法,局部变量,成员变量 final修饰类:不能有子类 final修饰方法:不能被重写 ...

  • 面向对象,多态

    final:修饰类,方法,变量 final修饰类:此类无法被继承; final修饰方法:不能被重写; final修...

  • 谈谈final、finally、 finalize有什么不同?

    他们在Java中没有相同的地方 final 是修饰符,可以用来修饰类,表示不可被继承修饰方法,表示不能被重写修饰变...

  • No.6final修饰符详解

    final作为java中的非访问修饰符可用于修饰类,接口,变量,方法; 被final修饰的类: final可以修饰...

  • java(final和lambda表达式)

    final修饰类表示该类不能被继承,final修饰方法表示该方法不能被重写(override),final修饰变量...

网友评论

      本文标题:Java中final修饰的方法是否可以被重写示例详解

      本文链接:https://www.haomeiwen.com/subject/lhgnaktx.html