Search code examples
javareferencefinal

How to create a variable that can be set only once but isn't final in Java


I want a class that I can create instances of with one variable unset (the id), then initialise this variable later, and have it immutable after initialisation. Effectively, I'd like a final variable that I can initialise outside of the constructor.

Currently, I'm improvising this with a setter that throws an Exception as follows:

public class Example {

    private long id = 0;

    // Constructors and other variables and methods deleted for clarity

    public long getId() {
        return id;
    }

    public void setId(long id) throws Exception {
        if ( this.id == 0 ) {
            this.id = id;
        } else {
            throw new Exception("Can't change id once set");
        }
    }
}

Is this a good way of going about what I'm trying to do? I feel like I should be able to set something as immutable after it's initialised, or that there is a pattern I can use to make this more elegant.


Solution

  • Let me suggest you a little bit more elegant decision. First variant (without throwing an exception):

    public class Example {
    
        private Long id;
    
        // Constructors and other variables and methods deleted for clarity
    
        public long getId() {
            return id;
        }
    
        public void setId(long id) {
            this.id = this.id == null ? id : this.id;
        }
    
    }
    

    Second variant (with throwing an exception):

         public void setId(long id)  {
             this.id = this.id == null ? id : throw_();
         }
    
         public int throw_() {
             throw new RuntimeException("id is already set");
         }