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