17

I'm making a banking model, and an Account class has an accountNumber field. The account number should never change, but I cannot set the field as final because this will prevent the constructor from setting it.

If it's not possible to do this, it doesn't matter. It's just for a CS assignment so I want to make sure I'm doing it the best way I can.

Would the best implementation be to just make the field and its setter method private?

mikej
  • 65,295
  • 17
  • 152
  • 131
Matt
  • 11,157
  • 26
  • 81
  • 110
  • 5
    "this will prevent the constructor from setting it." are you sure about that? http://stackoverflow.com/questions/677595/initialize-final-variable-before-constructor-in-java – kasten Nov 15 '10 at 21:43
  • That's awesome, didn't know you could do that :D – Matt Nov 15 '10 at 21:46
  • You cannot change final static variable from within a constructor, because static variable is one for many instances. But final variable is able to be initialised inside of constructor. – Alexander.Iljushkin Mar 03 '13 at 16:56

4 Answers4

24

The constructor can set it if it is marked as final e.g. the following is legal:

public class BankAccount {

    private final int accountNumber;

    public BankAccount(int accountNumber) {
        this.accountNumber = accountNumber;
    }

}

In fact if a field is marked as final but not initialised in its declaration then it must be set in all constructors.

If you do not put a public setter on the class then the account number can't be changed from outside the class but marking it as final will also prevent it (accidentally) being changed by any methods inside the class.

mikej
  • 65,295
  • 17
  • 152
  • 131
  • 1
    If you declare something like private final String accountNumber = null the complier will complain. – Todd Nov 15 '10 at 21:46
  • 1
    @Todd, correct. Once set to `null` the final variable can't be reassigned. However if the declaration is just `private final String accountNumber;` then you can assign its value in the constructor. – mikej Nov 15 '10 at 21:49
  • the comment was intended for the questioner. I thought that might be the problem he was having. – Todd Nov 15 '10 at 22:05
4

If a variable is final it can (and must) be initialized in the constructor.

Pablo Fernandez
  • 103,170
  • 56
  • 192
  • 232
  • So if I declare the field like "private final accountNumber;" and then initialise it in the constructor like "accountNumber = 1234", that will work? And I can ONLY do that in the constructor? – Matt Nov 15 '10 at 21:42
  • Yes. All finals must be set in all constructors. – Pablo Fernandez Nov 15 '10 at 21:43
  • 5
    This isn't quite true, really. A final field can be initialized where it's declared, in an instance initialization block, or in a constructor. A static final field can be initialized where it's declared or in a static initialization block. – ColinD Nov 15 '10 at 21:58
0

When a variable is final, it absolutely MUST be declared in the constructor, whether in the constructor or when you declare it. So worry not, you can create a final variable for your object, and then if you don't immediately set its value when you declare it, then you'll have to set its value in the constructor. So, technically speaking, both these codes are correct :

public class BankAccount {

    private final int acctNumber;

    public BankAccount(int acctNumber) {
        this.acctNumber = acctNumber;
    }

}
public class BankAccount {

    private final int acctNumber = 12;

    public BankAccount(int acctNumber) {
    }

}
FlyingFish
  • 111
  • 7
-1

You can do this by doing something like private static final String accNumber = askAccNumber(); And then declare a function:

private static final String askAccNumber (){ //however you want to input your number }