在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,子类写成 void process(ArrayList —— 看似一样,实为重载;没加 @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)(Admin 是 User 子类)就不是重写,而是重载,且很可能导致多态调用失效。
- 协变只适用于返回值,不适用于参数
- 基本类型无协变(
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中的兼容性问题


