测试代码
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private String name;
public static void main(String[] args) {
List<User> list = new ArrayList<>();
list.add(new User("bb"));
list.forEach(u -> {
u.setName("aaa");
});
System.out.println(list);
List<String> list2 = new ArrayList<>();
list2.add("bb");
list2.forEach(u -> {
u = "aaa";
});
System.out.println(list2);
List<String[]> list3 = new ArrayList<>();
list3.forEach(arr -> {
arr = new String[]{"aaa"};
});
System.out.println(list3);
}
}
结果
[User(name=aaa)]
[bb]
[]
原因
list.forEach掉的底层是ArrayList的forEach
@Override
public void forEach(Consumer<? super E> action) {
Objects.requireNonNull(action);
final int expectedModCount = modCount;
@SuppressWarnings("unchecked")
final E[] elementData = (E[]) this.elementData;
final int size = this.size;
for (int i=0; modCount == expectedModCount && i < size; i++) {
action.accept(elementData[i]);
}
if (modCount != expectedModCount) {
throw new ConcurrentModificationException();
}
}
final E[] elementData = (E[]) this.elementData; 做了传参,然后把赋予的参数带到了action.accept(elementData[i]);中执行
如果是String、String[] 等基础类型,就会是值传递,导致后续的赋值失败
如果是引用对象类型,则传递得是引用,赋值会成功