Java 最终名单重新分配

Java 最终名单重新分配,java,list,collections,Java,List,Collections,将最终列表创建为 final List=new ArrayList() 不会让我重新分配列表,因为列表是最终的 list=newarraylist() 将给出编译错误 但在插入第16个元素后,必须创建一个新的ArrayList,其容量=oldCapacity*3/2+1,并且必须分配给list 在这种情况下,JVM如何允许重新分配最终列表 但在插入第16个元素后,必须创建一个新的ArrayList,其容量=oldCapacity*3/2+1,并且必须分配给list 否,将创建一个新的备份阵列(插

将最终列表创建为

final List=new ArrayList()

不会让我重新分配列表,因为列表是最终的

list=newarraylist()
将给出编译错误

但在插入第16个元素后,必须创建一个新的ArrayList,其容量=oldCapacity*3/2+1,并且必须分配给list

在这种情况下,JVM如何允许重新分配最终列表

但在插入第16个元素后,必须创建一个新的ArrayList,其容量=oldCapacity*3/2+1,并且必须分配给list

否,将创建一个新的备份阵列(插入第11个元素时)。后备数组是
ArrayList
的一个实例变量(定义为
transient Object[]elementData;
)。将对该实例变量执行赋值,该变量不是
final

不会创建新的
ArrayList
实例,并且
list
变量仍然引用同一实例


因此,在您描述的场景中,没有为最终变量赋值。

否。ArrayList不会被替换。相应地,备份阵列得到扩展

在向列表中添加元素时,ArrayList确保其具有足够的容量

public boolean add(E e) {
378         ensureCapacity(size + 1);  // Increments modCount!!
379         elementData[size++] = e;
380         return true;
381     }
这是确保能力的关键。如果需要,它会得到扩展

public void ensureCapacity(int minCapacity) {
179         modCount++;
180         int oldCapacity = elementData.length;
181         if (minCapacity > oldCapacity) {
182             Object oldData[] = elementData;
183             int newCapacity = (oldCapacity * 3)/2 + 1;
184             if (newCapacity < minCapacity)
185                 newCapacity = minCapacity;
186             // minCapacity is usually close to size, so this is a win:
187             elementData = Arrays.copyOf(elementData, newCapacity);
188         }
189     }
public-capacity(int-minCapacity){
179 modCount++;
180 int oldCapacity=elementData.length;
181如果(最小容量>旧容量){
182对象oldData[]=elementData;
183新容量=(旧容量*3)/2+1;
184如果(新容量<最小容量)
185新容量=最小容量;
186//minCapacity通常接近大小,因此这是一个胜利:
187 elementData=Arrays.copyOf(elementData,newCapacity);
188         }
189     }

而且,如果列表是
final
,则不能重新分配它。但是,您仍然可以通过方法添加和修改它的内部内容

ArrayList
包含一个对象
array
作为其属性。当列表“展开”时,实际上是
数组
对象展开,因此
数组
被重新创建(地址更改),而不是
数组列表
本身。

最终引用
没有更改,最终对象的内部仍然可以更改,除非它们是深度不变的。通常,不变性意味着集合的大小不能更改

例如:

    List<StringBuilder> list = new ArrayList<>();
    list.add(new StringBuilder("can we?"));
    Collection<StringBuilder> canNotChange = Collections.unmodifiableCollection(list);

    StringBuilder sb = canNotChange.iterator().next();
    sb.setCharAt(0, '!');

    System.out.println(canNotChange); // !an we?
List List=new ArrayList();
添加(新的StringBuilder(“我们可以吗”);
Collection canNotChange=集合。不可修改的集合(列表);
StringBuilder sb=canNotChange.iterator().next();
sb.setCharAt(0,!);
System.out.println(不能更改);/!我们?

是。。。这就是最后一个关键字的作用。若你们想让这个列表成为一个新的ArrayList,不要把它声明为FinalList,但你们到底为什么想要它呢?列表与数组不同。当它们“满”时,您添加了另一个元素,它们的大小会自动增加最终并不意味着immutable@JeroenSteenbeeke为了不改变对象的内容,您的对象必须是深度不可变的,而这不是通常不可变的实现方式@尤金很好地解释了我想表达的观点