Declare final variable, but set later

后端 未结 7 1558
梦毁少年i
梦毁少年i 2020-12-09 01:49

I know this is fairly simple topic, but I really want to wrap my head around it.

This is what I\'m trying to do, but it doesn\'t like the final modifier. Is there an

7条回答
  •  暖寄归人
    2020-12-09 02:02

    The following Worm (Write-Once-Read-Many) class could help in this kind of scenario.

    We could create a nested Wrapper class, that stores the final variable you need. To initialize this variable, you just should call a constructor of the wrapper object. When you call the method getData(), you will get a reference of the final variable in case it is initialized, otherwise, you will get null.

    The methods getData() and setData(T data) are required to be thread-safe. To provide it, we use a volatile modifier for the wrapper object. Reading a volatile variable is synchronized and writing to a volatile variable is synchronized, too. Even though some efforts were made to make this code thread-safe I didn't test it in this respect. Depending on the level of thread safety you may consider to make setter and getter synchronized.

    public class Worm {
        private volatile Wrapper wrapper;
    
        public Worm() {}
        public Worm(T data) throws IllegalAccessError
        {
            setData(data);
        }
    
        public T getData()
        {
            if (wrapper == null)
                return null;
            return wrapper.data;
        }
    
        public void setData(T data) throws IllegalAccessError
        {
            if (wrapper != null)
                throw new IllegalAccessError();
            else
                wrapper = this.new Wrapper<>(data);
        }
    
        @Override
        public boolean equals(Object obj) {
            if (this == obj) {
                return true;
            }
            if (obj == null) {
                return false;
            }
            if (getClass() != obj.getClass()) {
                return false;
            }
            final Worm other = (Worm) obj;
            return Objects.equals(this.getData(), other.getData());
        }
    
        @Override
        public int hashCode() {
            return Objects.hashCode(this.getData());
        }
    
        final private class Wrapper {
            final private T data;
    
            Wrapper(T data) {
                this.data = data;
            }
        }
    }
    

提交回复
热议问题