java.util.ConcurrentModificationException
工作中碰到个ConcurrentModificationException。代码如下:
List list = ...;
for(Iterator iter = list.iterator(); iter.hasNext();) {
Object obj = iter.next();
...
if(***) {
list.remove(obj);
}
}
在执行了remove方法之后,再去执行循环,iter.next()的时候,报java.util.ConcurrentModificationException(当然,如果remove的是最后一条,就不会再去执行next()操作了)
下面来看一下源码
public interface Iterator<E> {
boolean hasNext();
E next();
void remove();
}
public interface Collection<E> extends Iterable<E> {
...
Iterator<E> iterator();
boolean add(E o);
boolean remove(Object o);
...
}
这里有两个remove方法
接下来来看看AbstractList
public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> {
//AbstractCollection和List都继承了Collection
protected transient int modCount = 0;
private class Itr implements Iterator<E> { //内部类Itr
int cursor = 0;
int lastRet = -1;
int expectedModCount = modCount;
public boolean hasNext() {
return cursor != size();
}
public E next() {
checkForComodification(); //特别注意这个方法
try {
E next = get(cursor);
lastRet = cursor++;
return next;
} catch(IndexOutOfBoundsException e) {
checkForComodification();
throw new NoSuchElementException();
}
}
public void remove() {
if (lastRet == -1)
throw new IllegalStateException();
checkForComodification();
try {
AbstractList.this.remove(lastRet); //执行remove对象的操作
if (lastRet < cursor)
cursor--;
lastRet = -1;
expectedModCount = modCount; //重新设置了expectedModCount的值,避免了ConcurrentModificationException的产生
} catch(IndexOutOfBoundsException e) {
throw new ConcurrentModificationException();
}
}
final void checkForComodification() {
if (modCount != expectedModCount) //当expectedModCount和modCount不相等时,就抛出ConcurrentModificationException
throw new ConcurrentModificationException();
}
}
}
remove(Object o)在ArrayList中实现如下:
public boolean remove(Object o) {
if (o == null) {
for (int index = 0; index < size; index++)
if (elementData[index] == null) {
fastRemove(index);
return true;
}
} else {
for (int index = 0; index < size; index++)
if (o.equals(elementData[index])) {
fastRemove(index);
return true;
}
}
return false;
}
private void fastRemove(int index) {
modCount++; //只增加了modCount
....
}
所以,产生ConcurrentModificationException的原因就是:
执行remove(Object o)方法之后,modCount和expectedModCount不相等了。然后当代码执行到next()方法时,判断了checkForComodification(),发现两个数值不等,就抛出了该Exception。
要避免这个Exception,就应该使用remove()方法。
这里我们就不看add(Object o)方法了,也是同样的原因,但没有对应的add()方法。一般嘛,就另建一个List了
分享到:
相关推荐
android 异常处理机制 ,关于android 如何处理异常。
android 异常捕捉和日志文件保存
Android异常捕获。捕获Android程序运行时候产生的Force Close错误,将错误写文件以及发送到指定邮箱。
Android 异常捕获以及上传到服务器
android 异常10s后重启
android 异常捕获源码.zip
Android 异常处理并把详细信息写入到文件中(包括手机型号,错误版本)
大家在Android移动开发的过程中经常会碰到程序异常崩溃,这个Demo是一个例子,可以把错误的日志保存在SD卡中方便测试和开发人员查看
使用android:process和Process.killProcess和UncaughtExceptionHandler完成Android应用程序不异常退出
无法运行android异常捕获存在sd卡中.rar,太多无法一一验证是否可用,程序如果跑不起来需要自调,部分代码功能进行参考学习。
实现UncaughtExceptionHandler拦截android异常,捕获全局异常,CrashHandler完整工程源码
Android捕获全局异常并写日志保存到sd卡,捕获异常消息后输出这个消息,可避免APP强制退出,抛出NullPointException玩玩哈,捕获全局异常是因为有的异常我们捕获不到,捕获时我们采用同步方法,以免单例多线程环境下...
android开发,异常处理,捕获异常上传到bugly,捕获异常库module化了。
ClassCastException 强制转换类失败异常 IllegalArgumentException 方法参数类型传入异常 IllegalStateException 非法的设备状态异常 NullPointException 传说中的空指针异常,如果一个对象不存在,你有对这个对象...
基于FWKN-SVM的Android异常入侵检测的研究.pdf
Android开发中异常捕获,异常信息存储在sd文件中,可跟踪。
通过日志文件形式保存安卓程序中出现的异常信息。
代码是关于android开发中,app异常信息自动保存在sd卡中
Android异常捕获机制
Android Crash Helper。安卓APP自定义异常处理器,Release状态下意外奔溃提示更加友好(代替系统默认的那个讨厌的对话框),不影响Debug模式下LogCat的打印。 ***************************************************...