0

I have a sample Java class for Bank Accounts:

public class Account {
    private Integer accountNumber;
    private Integer authPin;
    private Integer transactionPin;

    public Account(Integer accountNumber, Integer authPin, Integer transactionPin) {
        this.accountNumber = accountNumber;
        this.authPin = authPin;
        this.transactionPin = transactionPin;
    }

    public Integer getAccountNumber() {
        return accountNumber;
    }

    public void setAccountNumber(Integer accountNumber) {
        this.accountNumber = accountNumber;
    }

    public Integer getAuthPin() {
        return authPin;
    }

    public void setAuthPin(Integer authPin) {
        this.authPin = authPin;
    }

    public Integer getTransactionPin() {
        return transactionPin;
    }

    public void setTransactionPin(Integer transactionPin) {
        this.transactionPin = transactionPin;
    }

    @Override
    public String toString() {
        return accountNumber + "," + authPin + "," + transactionPin;
    }

    @Override
    public boolean equals(Object obj) {
        Account account = (Account) obj;
        return (this.accountNumber == account.getAccountNumber() && this.authPin == account.getAuthPin()
                && this.transactionPin == account.getTransactionPin());
    }

    @Override
    public int hashCode() {
        // TODO Auto-generated method stub
        return Objects.hashCode(this.getAccountNumber());
    }
}

As can be seen from the code snippet, I have overriden equals() and hashCode() methods. But when I am trying to do a simple assert check using jUnit, it is failing:

public class TestFileIO {
    Account account;

    @Before
    public void setUp() throws Exception {
        account = new Account(7, 2708, 2708);
    }

    @Test
    public void testReadTransactionFile() {
        assertEquals(account, new Account(7, 2708, 2708));
    }

Am I missing something important here?

Anurag
  • 723
  • 3
  • 13
  • 31
  • 1
    You're comparing integer references in your `equals` method (not mentioning the potential `ClassCastException`). Either use `int` or `Integer#equals()`. – Alexis C. Dec 16 '15 at 21:46
  • makes sense. Completely missed that point. – Anurag Dec 16 '15 at 21:51

1 Answers1

1

Instead of comparing Integer object references:

return (this.accountNumber == account.getAccountNumber() && this.authPin == account.getAuthPin()
        && this.transactionPin == account.getTransactionPin());

Because, Integer object references are not equals, for example this assertion fails:

// different identities -> this assertion fails
assert new Integer(7) == new Integer(7);

Use .equals:

return (Objects.equals(this.accountNumber, account.getAccountNumber())
        && Objects.equals(this.authPin, account.getAuthPin())
        && Objects.equals(this.transactionPin, account.getTransactionPin()));

If the fields are guaranteed to never be null, then change their type to int:

private int accountNumber;
private int authPin;
private int transactionPin;

Then you don't need to change the equals implementation, good as it is.

janos
  • 120,954
  • 29
  • 226
  • 236