使用断言来测试前提条件

时间:2013-08-11 00:34:03

标签: java

我正在进行一项学校作业,我应该使用断言来测试存款方法和构造函数的前提条件。我想出了方法,但我仍然坚持如何添加到构造函数。

这是我到目前为止所做的:

/**
   A bank account has a balance that can be changed by 
   deposits and withdrawals.
*/
public class BankAccount
{  
   private double balance;

   /**
      Constructs a bank account with a zero balance.
   */
   public BankAccount()
   {   
      balance = 0;
   }

   /**
      Constructs a bank account with a given balance.
      @param initialBalance the initial balance
   */
   public BankAccount(double initialBalance)
   {   
      balance = initialBalance;
   }

   /**
      Deposits money into the bank account.
      @param amount the amount to deposit
   */
   public void deposit(double amount)
   {  
      assert amount >=0;

       double newBalance = balance + amount;
      balance = newBalance;
   }

   /**
      Withdraws money from the bank account.
      @param amount the amount to withdraw
   */
   public void withdraw(double amount)
   {   
      double newBalance = balance - amount;
      balance = newBalance;
   }

   /**
      Gets the current balance of the bank account.
      @return the current balance
   */
   public double getBalance()
   {   
      return balance;
   }
}

3 个答案:

答案 0 :(得分:5)

/**
   Constructs a bank account with a zero balance.
*/
public BankAccount()
{   
   this(0);
}

/**
   Constructs a bank account with a given balance.
   @param initialBalance the initial balance
*/
public BankAccount(double initialBalance)
{   
    assert initialBalance >= 0;
    balance = initialBalance;
}

立即创建任何非法BankAccount会导致异常(如果启用了断言)。

断言几乎可以放在代码的任何地方。它们用于调试目的,如果禁用它们将无效(例如在生产期间)。

如果bankaccount的目的始终是肯定的,您可能想要添加其他断言,例如:

/**
   Withdraws money from the bank account.
   @param amount the amount to withdraw
*/
public void withdraw(double amount)
{   
    assert amount <= this.balance;

    this.balance -= amount;
}

同样,断言仅用于调试,您不应该尝试捕获它们。任何断言异常都表示程序中存在错误(或断言语句中的错误)。

因此不应使用以下内容:

try
{
    BankAccount newbankaccount = new BankAccount(5);
    newbankaccount.withdraw(6.0);
}
catch (Exception e)
{
    // illegal withdrawal
}

相反,你应该检查前提条件。

BankAccount newbankaccount = new BankAccount(5);
if (newbankaccount.getBalance() < 6.0)
{
    // illegal withdrawal
}
else
    newbankaccount.withdraw(6.0);

如果应用程序中存在逻辑错误,则只应触发断言异常。

答案 1 :(得分:4)

关于何时使用Assertions我的2美分;

使用断言时,请不要将其与Exception的使用混淆。

  • 在检查前置条件,后置条件和私有/内部代码的不变量时使用断言

  • 使用断言向您自己或您的开发团队提供反馈

  • 在检查不太可能发生的事情时使用断言,否则意味着您的应用程序中存在严重错误。

  • 使用断言来陈述您知道的事情

  • 检查传递给公共或受保护方法和构造函数的参数
  • 使用例外

请看这个:

    public class BankAccount
    {  
        private double balance;

        /**
           Constructs a bank account with a zero balance.
        */
        public BankAccount()
        {   
            balance = 0;

            // assert is NOT used to validate params of public methods
            // if ( !isValidBalance(amount) ) {
            //     throw new IllegalArgumentException("Amount should be greater than zero.");
           // }

            //check the class invariant
            assert hasValidBalance(): "Construction failed.";

        }        
           // Implements the class invariant.
           // Perform all checks on the state of the object.
           // One may assert that this method returns true at the end
           // of every public method.

          private boolean hasValidBalance(){
              return balance>0;
          }
    }

希望这有帮助。

答案 2 :(得分:2)

Bas已经涵盖了关于断言的重要部分。基本上,将在生产代码中跳过,但可以在调试期间启用。

考虑到这一点,我会扩展您的银行帐户代码的行为,以实际使用常规Java if语句;因为存入负数(或取消负数)总是错误的。