在Java里方法重写是如何实现的_Java方法重写规则说明

发布时间 - 2026-01-27 00:00:00    点击率:
Java方法重写必须发生在父子类继承关系中,本质是运行时多态,要求方法签名完全一致(参数类型严格相同、返回值可协变),private/static/构造方法不可重写,@Override注解用于编译期校验。

重写必须发生在父子类之间

Java 的方法重写(Override)本质是运行时多态的体现,前提是子类继承父类后,用相同签名的方法提供新实现。不是继承关系的两个类,即使方法名、参数、返回值完全一样,也不算重写,只是巧合同名。

常见错误现象:private 方法无法被重写(因为子类根本不可见),static 方法看似“重写”实为隐藏(StaticMethodHiding),调用行为由编译时类型决定,而非运行时对象类型。

  • 必须有 extends 关系,接口实现用 @Override 标注的是对 interface 中默认/抽象方法的实现,不是传统意义的重写
  • 父类方法不能是 final,否则编译报错:Cannot override the final method from XXX
  • 子类方法访问修饰符不能比父类更严格(如父类是 protected,子类不能是 private

@Override 注解不是可选的装饰,而是编译器校验开关

加不加 @Override 不影响 JVM 运行时是否执行重写逻辑,但它能防止你“以为自己在重写”,结果因拼写错误、参数类型偏差或父类方法被删改而意外变成重载(Overload)或新方法。

例如:父类有 void process(List data),子类写成 void process(ArrayList data) —— 看似一样,实为重载;没加 @Override 就不会报错,但运行时根本不会调用这个方法。

  • IDE 通常默认提示添加 @Override,建议始终开启并保留
  • 如果编译器报错 Method does not override method from its superclass,先检查方法签名是否完全一致(包括泛型擦除后参数类型、返回值协变性)
  • Java 5 起支持该注解,Java 8 后也适用于实现接口默认方法

返回值类型允许协变,但参数类型必须严格一致

重写时,子类方法的返回值可以是父类返回值类型的子类型(协变返回类型),这是 Java 5 引入的合法优化。但所有参数类型必须与父类方法**逐个完全相同**(考虑泛型擦除后的原始类型),不能宽化也不能窄化。

典型反例:Object get() 在父类中,子类写 String get() 是合法协变;但若父类是 void save(User u),子类写 void save(Admin u)AdminUser 子类)就不是重写,而是重载,且很可能导致多态调用失效。

  • 协变只适用于返回值,不适用于参数
  • 基本类型无协变(int 不能改成 long),包装类也不行(Integer 不能改成 Number
  • 泛型方法重写要特别小心:父类 T parse(String s),子类不能改成 T parse(String s),类型变量约束不参与重写判定,仅看擦除后签名

构造方法、静态方法、私有方法都不能被重写

这三类方法在字节码层面就不具备重写能力:构造方法名固定为 ,属于实例初始化专用;静态方法绑定在类上,通过类名直接调用;私有方法连继承都不存在,自然谈不上重写。

容易混淆的点:子类定义一个跟父类 static 方法同名同参的方法,编译通过,但这是“隐藏(hiding)”,不是重写。调用时取决于引用变量声明类型,而非实际对象类型。

  • 试图重写 private void init() 会静默变成子类自己的新方法,父类调用仍走原逻辑
  • static 方法隐藏可通过 SuperClass.method()SubClass.method() 显式调用,但无法通过多态触发
  • 构造方法永远不参与重写机制,子类构造器第一行默认或显式调用 super(),那是初始化链,不是重写
class Animal {
   

public Object speak() { return "sound"; } protected static void breathe() { System.out.println("breathe"); } }

class Dog extends Animal { @Override public String speak() { return "woof"; } // ✅ 协变返回

@Override
public void breathe() { /* 编译失败:无法重写 static 方法 */ }

public static void breathe() { /* ✅ 隐藏,非重写 */ }

}

重写真正起作用的地方,永远在「通过父类引用调用子类实例方法」这一瞬间。很多问题其实不出在语法规则,而出在没想清楚:这里到底有没有发生向上转型?引用类型和实际类型是否分离?


# java  # 字节  # speak  # jvm  # Static  # String  # Integer  # Object  # 多态  # 父类  # 子类  # 引用调用  # int  # void  # 继承  # 接口  # 值类型  # 引用类型  # private  # protected  # Interface  # 泛型  # number  # 对象  # ide  # 重写  # 返回值  # 报错  # 这是  # 就不  # 适用于  # 擦除  # 而非 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: 实例解析Array和String方法  在线ppt制作网站有哪些软件,如何把网页的内容做成ppt?  如何安全更换建站之星模板并保留数据?  学生网站制作软件,一个12岁的学生写小说,应该去什么样的网站?  如何用手机制作网站和网页,手机移动端的网站能制作成中英双语的吗?  jQuery 常见小例汇总  Laravel如何配置任务调度?(Cron Job示例)  在centOS 7安装mysql 5.7的详细教程  Laravel如何实现API版本控制_Laravel版本化API设计方案  如何在IIS7中新建站点?详细步骤解析  Laravel如何使用Eloquent ORM进行数据库操作?(CRUD示例)  详解Oracle修改字段类型方法总结  Laravel如何实现一对一模型关联?(Eloquent示例)  简单实现Android验证码  宙斯浏览器视频悬浮窗怎么开启 边看视频边操作其他应用教程  韩国网站服务器搭建指南:VPS选购、域名解析与DNS配置推荐  Win11任务栏卡死怎么办 Windows11任务栏无反应解决方法【教程】  Laravel如何实现URL美化Slug功能_Laravel使用eloquent-sluggable生成别名【方法】  如何用PHP工具快速搭建高效网站?  免费网站制作appp,免费制作app哪个平台好?  Laravel的HTTP客户端怎么用_Laravel HTTP Client发起API请求教程  Laravel怎么实现验证码功能_Laravel集成验证码库防止机器人注册  昵图网官方站入口 昵图网素材图库官网入口  Firefox Developer Edition开发者版本入口  Laravel如何记录日志_Laravel Logging系统配置与自定义日志通道  怎么制作一个起泡网,水泡粪全漏粪育肥舍冬季氨气超过25ppm,可以有哪些措施降低舍内氨气水平?  如何快速使用云服务器搭建个人网站?  Laravel如何与Pusher实现实时通信?(WebSocket示例)  Laravel如何设置定时任务(Cron Job)_Laravel调度器与任务计划配置  JavaScript模板引擎Template.js使用详解  Windows Hello人脸识别突然无法使用  手机软键盘弹出时影响布局的解决方法  如何批量查询域名的建站时间记录?  千问怎样用提示词获取健康建议_千问健康类提示词注意事项【指南】  湖南网站制作公司,湖南上善若水科技有限公司做什么的?  Laravel的契約(Contracts)是什么_深入理解Laravel Contracts与依赖倒置  Laravel如何使用Guzzle调用外部接口_Laravel发起HTTP请求与JSON数据解析【详解】  如何快速生成专业多端适配建站电话?  Laravel如何配置和使用队列处理异步任务_Laravel队列驱动与任务分发实例  Laravel如何实现多级无限分类_Laravel递归模型关联与树状数据输出【方法】  打造顶配客厅影院,这份100寸电视推荐名单请查收  如何用PHP快速搭建CMS系统?  JS中使用new Date(str)创建时间对象不兼容firefox和ie的解决方法(两种)  Laravel如何使用Telescope进行调试?(安装和使用教程)  网站设计制作书签怎么做,怎样将网页添加到书签/主页书签/桌面?  教学论文网站制作软件有哪些,写论文用什么软件 ?  Laravel的辅助函数有哪些_Laravel常用Helpers函数提高开发效率  Mybatis 中的insertOrUpdate操作  如何确保FTP站点访问权限与数据传输安全?  如何解决hover在ie6中的兼容性问题