1. 主页 > 大智慧

Java方法重写必知:5个常见错误与规避方法

(开篇暴击)
??"为什么我的@Override注解突然变黄了?"??、"明明照着教程写的代码,运行结果就是不对!"——这些抓狂瞬间,老程序员看了都直呼内行。今天咱们就把这些坑一个个填平,保你以后少掉几根头发!


一、访问权限越改越小(父类public你改private)

??这是新人最容易翻车的地方??,就像给自家大门装了三道锁,结果钥匙全丢了。

??踩坑现场还原??
父类里写着public void sendMessage(),子类心血来潮改成private void sendMessage()。这时候编译器会直接甩脸子:"error: 正在尝试分配更低的访问权限"

??避坑指南??
记住这个口诀:??"父宽子严,立马翻船"??。访问权限只能越改越开放:

  • public → 必须保持public
  • protected → 可以改成public
  • 默认权限 → 可以改成protected或public

举个正确例子:

java复制
class Parent {
    protected void backupData() { /*...*/ }
}

class Child extends Parent {
    @Override
    public void backupData() { /* 这里改成public完全OK */ }
}

二、方法签名对不上(参数/返回类型暗搓搓改动)

??这种错误就像做菜忘放盐??,表面看着没问题,实际完全不是那个味。

??典型翻车姿势??
父类方法:void connect(String ip)
子类改成:void connect(String ip, int port) → 这根本不是重写,而是新建了个方法!

??救命技巧??

  1. 必须使用@Override注解(这是你的护身符!)
  2. 用IDE的自动生成功能(IntelliJ按Ctrl+O,Eclipse按Alt+Shift+S)
  3. 检查返回类型:基本类型必须完全一致,引用类型可以是父类返回类型的子类

比如这样就不会错:

java复制
class Animal {
    public Number getAge() { return 18; }
}

class Dog extends Animal {
    @Override
    public Integer getAge() { return 2; } // Integer是Number的子类,合法!
}

三、跟静态方法较劲(误把隐藏当重写)

??静态方法根本不是重写的菜??,这个知识点坑过无数英雄好汉。

??大型迷惑现场??

java复制
class Parent {
    static void print() { System.out.println("父类静态"); }
}

class Child extends Parent {
    static void print() { System.out.println("子类静态"); } // 这是隐藏,不是重写!
}

这时候用Parent p = new Child(); p.print(); 输出的还是父类版本!

??正确打开方式??

  • 记住静态方法属于类,不属于对象
  • 想修改静态方法行为?直接类名调用最靠谱
  • 实在要用多态效果,改用实例方法

四、异常处理放飞自我(乱抛新异常)

??异常处理不讲究,分分钟让你程序崩溃??。

??危险操作示范??
父类方法声明:void readFile() throws IOException
子类改成:void readFile() throws SQLException → 直接报错没商量!

??安全守则??

  • 子类方法抛出的异常必须是父类异常的子类
  • 可以少抛或不抛异常,但不能新增更宽泛的异常
  • 运行时异常不受限制(但也要谨慎使用)

看个合规操作:

java复制
class Parent {
    void process() throws FileNotFoundException { /*...*/ }
}

class Child extends Parent {
    @Override
    void process() { /* 完全不抛异常,合法! */ }
}

五、无视final封印(强行修改不可变方法)

??final方法就像被封印的古籍??,谁碰谁倒霉。

??作死行为实录??

java复制
class Parent {
    public final void securityCheck() { /*...*/ }
}

class Child extends Parent {
    @Override  // 这里会直接报错!
    public void securityCheck() { /* 想搞事情?没门! */ }
}

编译器会直接甩你一脸错误:Cannot override the final method

??生存法则??

  • 看到final方法绕道走
  • 想修改final方法的行为?考虑用组合替代继承
  • 重要核心方法才用final,别随便给自己挖坑

老司机经验加油站

这些年带团队见过太多奇葩错误,最离谱的一次是新人把equals方法重写成public boolean equals(MyClass obj),导致整个系统的对象比较全乱了套。所以特别提醒:??重写Object类方法时,参数类型必须是Object!??

还有个冷知识:重写方法的??返回类型协变??特性是Java5才加入的。所以如果你看到老代码里子类方法返回类型和父类完全一致,别觉得人家不懂,可能是为了兼容旧版本。

最后送大家一句话:??"重写不是乱写,继承要有底线"??。把这些规则吃透,下次遇到问题至少能快速定位方向。毕竟在编程世界里,知道哪里不能踩往往比知道捷径更重要,你说是不是这个理?

本文由嘻道妙招独家原创,未经允许,严禁转载