【问题标题】:Duplicating code for throwing exceptions复制代码以引发异常
【发布时间】:2015-11-15 10:23:11
【问题描述】:

假设我有这个代码:

public class Car {
    private int fuel;

    public Car(int fuel) {
        if (fuel < 0) {
            throw new IllegalArgumentException("Can't be negative");
        }
        this.fuel = fuel;
    }

    public void setFuel(int fuel) {
        if (fuel < 0) {
            throw new IllegalArgumentException("Can't be negative");
        }
        this.fuel = fuel;
   }

我的问题是,我能否避免在构造函数和设置器中重复代码?

【问题讨论】:

标签: java


【解决方案1】:

为什么不把构造函数改成调用setter:

public Car(int fuel) {
    setFuel(fuel);
}

【讨论】:

  • 我也想过这个,但后来读到:stackoverflow.com/questions/4893558/…
  • 在 Jon Skeets 接受的答案中,他更喜欢保持类不可变。所以在他的例子中没有设置器,所有的逻辑都包含在构造函数中。但是,如果您想要 setter 和可变对象,最好尽可能重用代码。
  • @krock:这是答案的后续方面。 Jon 主要说的是:“在大多数情况下,我会直接设置变量。方法通常期望实例在它们被调用时已经完全形成。”(绝对是,使对象不可变在可能的情况下往往是一个有用的设计选择。这通常是不可能的。)
【解决方案2】:

与大多数重复代码一样,您可以将其分解为方法。

public class Car {
    private int fuel;

    public Car(int fuel) {
        checkFuel(fuel);
        this.fuel = fuel;
    }

    public void setFuel(int fuel) {
        checkFuel(fuel);
        this.fuel = fuel;
    }

    private static void checkFuel(int fuel) {
        if (fuel < 0) {
            throw new IllegalArgumentException("'fuel' argument can't be negative");
        }
    }

为什么不从构造函数中调用setFuel?因为在完全初始化之前从构造函数中调用实例的方法可能是错误的来源。考虑:子类覆盖setFuel 并添加副作用。更多关于 in this question and its answers.

这是另一种方式,也是将其封装在一个方法中:

public class Car {
    private int fuel;

    public Car(int fuel) {
        this.privateSetFuel(fuel);
    }

    public void setFuel(int fuel) {
        this.privateSetFuel(fuel);
    }

    private void privateSetFuel(int fuel) {
        if (fuel < 0) {
            throw new IllegalArgumentException("'fuel' argument can't be negative");
        }
        this.fuel = fuel;
    }

旁注:注意我在异常消息中添加了参数的名称。

【讨论】:

    【解决方案3】:

    直接从构造函数调用setter:

    public class Car {
        private int fuel;
    
        public Car(int fuel) {
            setFuel(fuel);
        }
    
        public void setFuel(int fuel) {
            if (fuel < 0) {
                throw new IllegalArgumentException("Can't be negative");
            }
            this.fuel = fuel;
       }
    

    【讨论】:

      【解决方案4】:

      是的。从您的构造函数中调用 setFuel(燃料)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2022-01-23
        • 1970-01-01
        • 1970-01-01
        • 2023-03-07
        • 2011-11-11
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多