You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

构造方法参数顺序引发异常及Setter相关技术疑问

构造方法调用Setter出现异常行为的问题

为避免代码重复,我在Java构造方法中调用Setter方法,原本认为传入正确参数时参数顺序不会影响执行结果,但实际出现了不符合预期的行为。

相关代码

public class Wall {
    private double width;
    private double height;

    public Wall() {}

    public Wall(double width, double height) {
        this.setHeight(height); // 调用Setter设置字段,但出现异常行为
        this.setWidth(width);  // 看起来没被执行?

    }

    public double getWidth() {
        return width;
    }

    public void setWidth(double width) {
        if (width <= 0) {
            this.width = 0;
            System.out.println("INVALID VALUE - The width of the wall is updated to :" + 0.0);

        } else {
            this.width = width;
            System.out.println("The width of the wall is updated to :" + width);
        }
    }

    public double getHeight() {
        return height;
    }

    public void setHeight(double height) {
        if (height <= 0) {
            this.height = 0;
            System.out.println("INVALID VALUE - The width of the wall is updated to :" + 0.0);
        } else {
            this.height = height;
            System.out.println("The height of the wall is updated to :" + height);
        }
    }

    public double getArea() {
        return width * height;
    }

}

输出结果

原构造方法参数顺序下的输出

The width of the wall is updated to :10.0 // 符合预期
INVALID VALUE - The width of the wall is updated to :0.0 // 不符合预期

构造方法参数顺序反转后的输出

INVALID VALUE - The width of the wall is updated to :0.0 // 符合预期
The height of the wall is updated to :10.0 // 符合预期

疑问

  • 构造方法中的Setter方法为何并非全部被调用?
  • 这些Setter方法能否设为静态并对正在创建的对象进行操作?
  • 这种场景下的正确实现方式是什么?

解答

1. 所有Setter都被调用了,是输出信息错误导致误解

你在setHeight方法里犯了一个低级错误:当height参数非法时,打印的提示文本是**"INVALID VALUE - The width of the wall is updated to :"**,这明显是复制setWidth的代码时没修改字段名称。

比如你传入参数(10.0, -5.0)时:

  • 先执行setHeight(-5.0),触发非法判断,修改的是height字段为0,但错误打印了"width更新为0"的信息
  • 接着执行setWidth(10.0),正常修改width字段并打印正确信息
    但因为提示文本错误,你误以为setWidth没被调用,实际上两个Setter都执行了,只是输出信息混淆了操作的字段。

2. 不能将Setter设为静态来操作实例

静态方法属于类本身,不属于任何具体对象,在静态方法里无法直接访问非静态的实例变量(width和height都是实例变量),也不能使用this关键字指向当前正在创建的对象。所以静态Setter根本无法修改实例的字段,这个思路不可行。

3. 两种正确实现方案

方案一:提取统一校验逻辑到私有辅助方法

把参数校验的逻辑抽成一个私有方法,构造方法和Setter都调用这个方法,既避免代码重复,又能保证逻辑一致:

public class Wall {
    private double width;
    private double height;

    public Wall() {}

    public Wall(double width, double height) {
        this.width = validateDimension(width, "width");
        this.height = validateDimension(height, "height");
    }

    public double getWidth() {
        return width;
    }

    public void setWidth(double width) {
        this.width = validateDimension(width, "width");
    }

    public double getHeight() {
        return height;
    }

    public void setHeight(double height) {
        this.height = validateDimension(height, "height");
    }

    public double getArea() {
        return width * height;
    }

    // 私有辅助方法:统一处理维度参数的校验和提示
    private double validateDimension(double value, String dimensionName) {
        if (value <= 0) {
            System.out.printf("INVALID VALUE - The %s of the wall is updated to :%.1f%n", dimensionName, 0.0);
            return 0;
        } else {
            System.out.printf("The %s of the wall is updated to :%.1f%n", dimensionName, value);
            return value;
        }
    }
}

方案二:修正Setter的错误后继续使用构造调用Setter

如果你坚持用构造方法调用Setter,首先要修正setHeight里的错误提示文本,确保输出信息准确:

public void setHeight(double height) {
    if (height <= 0) {
        this.height = 0;
        // 将这里的width改为height,修正提示文本
        System.out.println("INVALID VALUE - The height of the wall is updated to :" + 0.0);
    } else {
        this.height = height;
        System.out.println("The height of the wall is updated to :" + height);
    }
}

注意:如果这个类会被子类继承,构造方法调用Setter可能引发意外(父类构造执行时子类还未完成初始化,若子类覆盖了Setter,会执行子类的逻辑)。如果类不会被继承,这个方案没问题;若涉及继承,优先选方案一。


内容的提问来源于stack exchange,提问作者Taha Sk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 21:10:28