Jose M.
Jose M.

Reputation: 2350

Using assertion to test the precondition

I am working on a school assignment, I am supposed to use assertions to test the preconditions of the deposit method and the constructor. I figured out the method, but I am stuck on how to add to the constructor.

Here is what I have so far:

/**
   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;
   }
}

Upvotes: 5

Views: 3070

Answers (3)

JNL
JNL

Reputation: 4713

My 2 cents on when to use Assertions;

When you use Assertions, please do not confuse it with the use for Exception.

  • Use assertions when checking pre-conditions, post-conditions and invariants of private/internal code

  • Use assertions to provide feedback to yourself or your developer team

  • Use assertions when checking for things that are very unlikely to happen otherwise it means that there is a serious flaw in your application.

  • Use assertions to state things that you know are to be true.

  • Use Exceptions when checking parameters passed to public or protected methods and constructors

Please See this:

    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;
          }
    }

Hope this helps.

Upvotes: 4

Edwin Buck
Edwin Buck

Reputation: 70949

Bas has covered the important parts about assertions. Basically, the will be skipped in production code, but can be enabled during debugging.

With that in mind, I would extend the behavior of your bank account code to actually use regular Java if statements; as it is always an error to deposit a negative amount (or to withdraw a negative amount).

Upvotes: 2

bas
bas

Reputation: 1678

/**
   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;
}

Creating any illegal BankAccount immediately results in an exception (if assertions are enabled).

Assertions can be placed practically everywhere in the code. They are for debugging purposes and will have no effect if you disable them (e.g. during production).

If the purpose of the bankaccount is to always be positive, you might want to add additional assertions, for example:

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

    this.balance -= amount;
}

Again, assertions are only for debugging, you should not try to catch them. Any assertion-exception indicates a fault in your program (or a fault in the assertion statement).

So the following should NOT be used:

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

Instead, you should check the pre-conditions.

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

An assertion-exception should only fire if there is a logic error in your application.

Upvotes: 5

Related Questions