java解惑之要点何在

本文详细解释了在Java类构造器中调用可覆盖方法可能导致的问题,并通过实例展示了如何正确初始化类属性,以避免潜在的运行时异常和性能影响。同时,提供了解决方案,包括移除不必要的初始化操作和优化toString方法,确保代码的健壮性和高效性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

千万不要在构造器中调用可覆盖的方法。

package ch6_classy_puzzlers.puzzle_51;

class Point {
    protected final int x, y;
    private final String name; // Cached at construction time
    Point(int x, int y) {
        this.x = x;
        this.y = y;
        name = makeName();//(3) Invoke subclass method
    }

    protected String makeName() {
        return "[" + x + "," + y + "]";
    }

    public final String toString() {
        return name;
    }
}

public class ColorPoint extends Point {
    private final String color;
    ColorPoint(int x, int y, String color) {
        super(x, y);//(2) Chain to Point  Constructor 
        this.color = color;//(5) Initialize blank final- Too late  
    }

    protected String makeName() {
       // (4) Executes before subclass constructor body!
       return super.makeName() + ":" + color;
    }

    public static void main(String[] args) {
    	//(1) Invoke subclass constructor 
        System.out.println(new ColorPoint(4, 2, "purple"));
    }
}
它的输出为[4,2]:null,请看注释里的语句执行顺序。
其实我们可以将其Point类的中的Point构造函数移除对name的初始化,并写一个final synchronized String toString方法,tostring里面如果name为空,则对其初始化。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值