真实面经题目 · 原创解析

java中重载和重写有什么区别,分别用什么关键字?

Java 中重载是同一个类或继承关系中方法名相同、参数列表不同,属于编译期静态分派;重写是子类重新实现父类或接口中可被覆盖的实例方法,属于运行期动态分派。二者都没有专门关键字,@Override 是注解不是关键字。

出现于:阿里巴巴 · 后端开发

60 秒回答模板

重载和重写可以从定义、规则和分派时机三方面区分。重载 overload 是方法名相同但参数列表不同,参数个数、类型或顺序不同都可以构成重载;它不依赖继承关系,同一个类里就能发生。方法签名不包含返回值,所以仅返回值不同不能构成重载。重载在编译期由编译器根据调用处的声明类型、实参类型、自动装箱、类型提升和可变参数规则选择目标方法。重写 override 是子类对父类或接口中可被重写的实例方法提供新的实现,要求方法名和参数列表一致,返回值相同或协变,访问权限不能比父类更窄,不能抛出更宽的受检异常。重写在运行期按对象真实类型动态分派,是 Java 多态的关键机制。static 方法属于类,子类同名同参是隐藏而不是重写;final 方法不能重写;private 方法对子类不可见,不能被重写;构造器不能继承,所以不能重写但可以重载。Java 没有 override 或 overload 关键字,@Override 是注解,建议用于重写校验。

考点 重载定义
主线 重写定义
易错点 认为重载和重写都有专门关键字,混淆了 @Overrid…

深入解析

01

重载定义

重载指同名方法拥有不同参数列表,参数个数、参数类型或参数顺序不同都可以。它可以发生在同一个类中,也可以结合继承关系出现,但不要求必须有父子类。返回值不同、访问修饰符不同或 throws 不同,单独都不能构成重载。

02

重写定义

重写指子类对父类或接口中可被重写的实例方法提供新的实现。它要求方法签名一致,体现的是继承和多态关系。调用方面向父类引用调用方法时,运行期会根据实际对象类型执行子类实现,因此它是 Java 动态多态的主要来源。

03

分派时机

重载属于编译期静态分派,编译器根据调用处能看到的方法集合和实参静态类型选择最匹配的方法。重写属于运行期动态分派,编译期先确定方法签名,运行期再根据对象真实类型选择具体实现,所以父类引用调用子类对象时仍能执行子类逻辑。

04

返回与异常

重载不能只靠返回值区分,因为调用表达式可能无法仅凭返回值确定目标方法。重写的返回值必须相同或协变,子类方法不能抛出比父类方法更宽的受检异常,可以不抛、少抛或抛更具体的受检异常;非受检异常不受这个规则严格限制。

05

访问权限

重写时子类方法访问权限不能比父类更窄,例如父类 public 方法不能重写成 protected。重载之间没有这种继承约束,只要方法签名能区分即可,但 API 设计上仍要避免制造难以理解的调用歧义。

06

特殊方法

static 方法属于类,不参与实例动态分派,子类同名同参 static 方法是隐藏。final 方法明确禁止重写。private 方法对子类不可见,不构成重写。构造器不会被继承,所以不能重写,但可以在同一个类中定义多个构造器形成重载。

易错点

  • 认为重载和重写都有专门关键字,混淆了 @Override 注解和关键字。
  • 以为返回值不同就能构成重载,忽略方法签名规则。
  • 把 static 方法当成重写,实际上它是方法隐藏。
  • 认为 private 方法可以被子类重写,忽略 private 不参与继承可见性。
  • 认为重写可以缩小访问权限或抛出更宽的受检异常。

面试官追问

返回值不同能不能构成重载?

不能。Java 方法签名主要由方法名和参数列表决定,不包含返回值。仅返回值不同会让调用解析产生歧义,因此编译器不允许。

父类引用指向子类对象时,重载和重写分别看什么?

重载先在编译期按引用静态类型和参数类型选定方法签名;如果这个签名对应的实例方法被子类重写,运行期再按对象真实类型分派到子类实现。

static 方法能重写吗?

不能。static 方法属于类,不参与实例虚方法分派。子类声明同名同参 static 方法叫方法隐藏,调用结果主要取决于引用或类名的静态类型。

@Override 有什么价值?

它让编译器检查当前方法是否真的覆盖了父类或接口方法。方法名拼错、参数写错、访问规则不满足时会直接报错,能减少隐藏 bug。