Skip to content

Question 2

Design a banking application where users can deposit and withdraw money.

  • Create a custom exception InsufficientFundsException that is thrown when a withdrawal request exceeds the current balance.
  • Demonstrate how to handle this custom exception using try-catch blocks.
  • Include a finally block to display the remaining balance after each transaction attempt.

Custom Exception: InsufficientFundsException.java

java
public class InsufficientFundsException extends Exception {

    private double amountShort; 
    // Optional: to store how much money was short

    public InsufficientFundsException(String message) {
        super(message);
    }

    public InsufficientFundsException(String message, double amountShort) {
        super(message);
        this.amountShort = amountShort;
    }

    public double getAmountShort() {
        return amountShort;
    }

    @Override
    public String getMessage() {
        if (amountShort > 0) {
            return super.getMessage() + " You are short by $" + String.format("%.2f", amountShort) + ".";
        }
        return super.getMessage();
    }
}

Bank Account Class: BankAccount.java

java
public class BankAccount {
    private String accountNumber;
    private String accountHolderName;
    private double balance;

    public BankAccount(String accountNumber, String accountHolderName, double initialBalance) {
        this.accountNumber = accountNumber;
        this.accountHolderName = accountHolderName;
        if (initialBalance < 0) {
            this.balance = 0;
            System.out.println("Initial balance cannot be negative. Set to $0.00.");
        } else {
            this.balance = initialBalance;
        }
    }

    public String getAccountNumber() {
        return accountNumber;
    }

    public String getAccountHolderName() {
        return accountHolderName;
    }

    public double getBalance() {
        return balance;
    }

    public void deposit(double amount) {
        if (amount <= 0) {
            System.out.println("Deposit amount must be positive.");
            // Or throw new IllegalArgumentException("Deposit amount must be positive.");
            return;
        }
        this.balance += amount;
        System.out.println("$" + String.format("%.2f", amount) + " deposited successfully.");
    }

    // Method that can throw the custom exception
    public void withdraw(double amount) throws InsufficientFundsException {
        if (amount <= 0) {
            System.out.println("Withdrawal amount must be positive.");
            // Or throw new IllegalArgumentException("Withdrawal amount must be positive.");
            return;
        }
        if (amount > this.balance) {
            double shortBy = amount - this.balance;
            throw new InsufficientFundsException("Withdrawal amount of $" 
	            + String.format("%.2f", amount) 
	            + " exceeds current balance.", shortBy);
        }
        this.balance -= amount;
        System.out.println("$" + String.format("%.2f", amount) + " withdrawn successfully.");
    }

    public void displayAccountInfo() {
        System.out.println("------------------------------------");
        System.out.println("Account Holder: " + accountHolderName);
        System.out.println("Account Number: " + accountNumber);
        System.out.println("Current Balance: $" + String.format("%.2f", balance));
        System.out.println("------------------------------------");
    }
}

Main Application: BankingApplicationDemo.java

java
public class BankingApplicationDemo {

    public static void main(String[] args) {
        BankAccount account1 = new BankAccount("ACC12345", "Alice Wonderland", 1000.00);
        account1.displayAccountInfo();

        performTransaction(account1, "deposit", 200.00);
        performTransaction(account1, "withdraw", 500.00);
        performTransaction(account1, "withdraw", 800.00); 
        // This will cause an exception
        
        performTransaction(account1, "deposit", 100.00);
        performTransaction(account1, "withdraw", 50.00);

        System.out.println("\n--- Trying to withdraw from an account with zero balance ---");
        BankAccount account2 = new BankAccount("ACC67890", "Bob The Builder", 0.00);
        account2.displayAccountInfo();
        performTransaction(account2, "withdraw", 50.00); 
        // This will also cause an exception
    }

    // Helper method to demonstrate try-catch-finally for transactions
    public static void performTransaction(BankAccount account, String transactionType, double amount) {
        System.out.println("\nAttempting to " + transactionType + " $" + String.format("%.2f", amount) + "...");
        try {
            if ("deposit".equalsIgnoreCase(transactionType)) {
                account.deposit(amount);
            } else if ("withdraw".equalsIgnoreCase(transactionType)) {
                account.withdraw(amount); 
                // This call might throw InsufficientFundsException
            } else {
                System.out.println("Invalid transaction type.");
            }
        } catch (InsufficientFundsException ife) {
            // Handle the custom exception specifically
            System.err.println("Transaction Failed! Error: " + ife.getMessage());
        } catch (IllegalArgumentException iae) {
            // Handle potential issues from deposit/withdraw validation (if we threw them)
            System.err.println("Invalid Argument: " + iae.getMessage());
        } catch (Exception e) {
            // A more generic catch block for any other unexpected runtime exceptions
            System.err.println("An unexpected error occurred: " + e.getMessage());
            e.printStackTrace(); // Good for debugging
        } finally {
            // This block ALWAYS executes, whether an exception occurred or not.
            System.out.println("--- Transaction Attempt Finished ---");
            System.out.println("Account: " + account.getAccountNumber() +
                               ", Remaining Balance: $" + String.format("%.2f", account.getBalance()));
            System.out.println("------------------------------------");
        }
    }
}

Expected Output:

------------------------------------
Account Holder: Alice Wonderland
Account Number: ACC12345
Current Balance: $1000.00
------------------------------------

Attempting to deposit $200.00...
$200.00 deposited successfully.
--- Transaction Attempt Finished ---
Account: ACC12345, Remaining Balance: $1200.00
------------------------------------

Attempting to withdraw $500.00...
$500.00 withdrawn successfully.
--- Transaction Attempt Finished ---
Account: ACC12345, Remaining Balance: $700.00
------------------------------------

Attempting to withdraw $800.00...
Transaction Failed! Error: Withdrawal amount of $800.00 exceeds current balance. You are short by $100.00.
--- Transaction Attempt Finished ---
Account: ACC12345, Remaining Balance: $700.00
------------------------------------

Attempting to deposit $100.00...
$100.00 deposited successfully.
--- Transaction Attempt Finished ---
Account: ACC12345, Remaining Balance: $800.00
------------------------------------

Attempting to withdraw $50.00...
$50.00 withdrawn successfully.
--- Transaction Attempt Finished ---
Account: ACC12345, Remaining Balance: $750.00
------------------------------------

--- Trying to withdraw from an account with zero balance ---
------------------------------------
Account Holder: Bob The Builder
Account Number: ACC67890
Current Balance: $0.00
------------------------------------

Attempting to withdraw $50.00...
Transaction Failed! Error: Withdrawal amount of $50.00 exceeds current balance. You are short by $50.00.
--- Transaction Attempt Finished ---
Account: ACC67890, Remaining Balance: $0.00
------------------------------------

Made with ❤️ for students, by a fellow learner.