Olá!
A questão não é o final do atributo. No construtor todo conteúdo da lista é adicionado nesta nova implementação de List, ou no seu caso de Collection.
Olhe a implementação de UnmodifiableList por exemplo. Veja que qualquer método que não realiza modificação de conteúdo faz praticamente a mesma coisa. Porém os métodos que modificam algo lançam UnsupportedOperationException.  Esta é a grande diferença em relação a implementação do ArrayList, o que explica sua diferença de comportamento.
Segue uma parte do código copiado para notar a diferença e facilitar a compreensão de todos.
static class UnmodifiableList<E> extends UnmodifiableCollection<E>
                                  implements List<E> {
        private static final long serialVersionUID = -283967356065247728L;
        final List<? extends E> list;
        UnmodifiableList(List<? extends E> list) {
            super(list);
            this.list = list;
        }
        public boolean equals(Object o) {return o == this || list.equals(o);}
        public int hashCode()           {return list.hashCode();}
        public E get(int index) {return list.get(index);}
        public E set(int index, E element) {
            throw new UnsupportedOperationException();
        }
        public void add(int index, E element) {
            throw new UnsupportedOperationException();
        }
        public E remove(int index) {
            throw new UnsupportedOperationException();
        }
        public int indexOf(Object o)            {return list.indexOf(o);}
        public int lastIndexOf(Object o)        {return list.lastIndexOf(o);}
        public boolean addAll(int index, Collection<? extends E> c) {
            throw new UnsupportedOperationException();
        }
        public ListIterator<E> listIterator()   {return listIterator(0);}
Espero ter ajudado. Abraço