重载与重写本质区别在于解决问题不同:重载为同一类提供多参数入口,发生于类内部;重写为子类定制继承方法行为,发生于父子类之间;重载要求参数列表不同,重写要求方法签名一致且有协变等放宽;重载绑定在编译时,重写绑定在运行时;重载约束少,重写须遵循“两同两小一大”规则,并推荐使用@Override注解。

本质区别不在名字像不像,而在它们解决的问题不同:重载是为同一个类提供多种参数组合的入口,重写是为子类定制继承来的方法行为。
发生位置完全不同
重载只出现在一个类内部。比如工具类里有多个 parse() 方法——parse(String)、parse(byte[])、parse(int),全在同一个类里,目的就是让调用更灵活。
重写一定发生在父子类之间。比如 ArrayList 继承 AbstractList 后,重新写了 size() 方法,这是为了适配自己的内部结构,不是新增功能,而是替换已有逻辑。
方法签名的要求相反
重载要求参数列表必须不同:类型、个数、顺序,三者至少一个有差别;方法名相同即可;返回值、修饰符、异常声明全都不影响重载判断。
立即学习“Java免费学习笔记(深入)”;
重写要求方法名和参数列表必须完全一致(连泛型擦除后的字节码签名都要匹配);返回值允许协变(如父类返回 Object,子类可返回 String),但不能更宽;访问权限不能缩小,异常不能扩大。
- 重载看“有没有不同参数”
- 重写看“是不是完全一样再加一点合理放宽”
绑定时机决定运行表现
重载由编译器在编译时就定死调用哪个方法。你写 calc(3.14),编译器直接选 calc(double),生成固定指令,运行中不会换。
重写由 JVM 在运行时根据对象实际类型动态决定。哪怕变量声明是 List list = new ArrayList();,调用 list.add() 时,JVM 看的是右边那个真实对象,所以执行的是 ArrayList 里的重写版本。
这就是为什么重载体现编译时多态,重写体现运行时多态。
规则约束力度差异明显
重载几乎没限制:可以是 private 或 public,可以抛任意异常,甚至能和父类的重载方法共存,互不干扰。
重写有硬性规则,常记作“两同两小一大”:
- 方法名、参数列表必须相同
- 返回值类型 ≤ 父类(协变允许)
- 抛出异常 ≤ 父类(范围更窄)
- 访问权限 ≥ 父类(不能缩小)
- 父类方法不能是
private、final或static
用 @Override 注解不是可选项,是强烈推荐的实践——它能让编译器提前发现拼写错误或签名不匹配,避免你以为重写了,其实只是新建了一个方法。


















