首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

为什么在使用List迭代器的next方法时会出现不兼容的类型错误,而在使用List的get方法时却不会呢?

在使用List迭代器的next方法时会出现不兼容的类型错误,而在使用List的get方法时却不会,是因为它们在处理元素类型的方式上有所不同。

List是一个有序的集合,可以通过索引来访问其中的元素。List的get方法通过索引获取元素,返回的是指定位置的元素对象。由于List在创建时需要指定元素的类型,因此在编译时就已经确定了元素的类型,所以在使用get方法时不会出现类型错误。

而List迭代器是用于遍历List集合的工具,它提供了一系列的方法来访问集合中的元素。在使用迭代器的next方法时,它返回的是一个Object类型的对象,而不是具体的元素类型。这是因为迭代器设计的初衷是为了能够处理各种类型的集合,而不仅仅局限于某一种类型。因此,在使用迭代器的next方法获取元素时,需要将返回的Object对象强制转换为实际的元素类型。如果在强制转换的过程中出现了类型不兼容的情况,就会抛出类型错误。

综上所述,使用List的get方法获取元素时不会出现类型错误,是因为在编译时已经确定了元素的类型;而使用List迭代器的next方法获取元素时可能会出现类型错误,是因为迭代器返回的是Object类型的对象,需要进行强制类型转换。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

在ArrayList的循环中删除元素,会不会出现问题?

) { // list.remove(iterator.next()); // } // } // 方法五:迭代器,使用迭代器的...} // } } } 这里我测试了五种不同的删除方法,一种是普通的 for 循环,一种是增强的 foreach 循环,还有一种是使用迭代器循环,一共这三种循环方式。...删除这种元素时,方法一在删除重复但不连续的元素时是正常的,但在删除重复且连续的元素时,会出现删除不完全的问题,这种删除方式也是用到了 ArrayList 中的 remove() 方法。...方法五中使用的是迭代器中的 remove() 方法,通过阅读 ArrayList 的源码可以发现,有两个私有内部类,Itr 和 ListItr,Itr 实现自 Iterator 接口,ListItr 继承...中的 remove() 方法,那为什么方法四会抛出并发修改异常而这里就没有问题呢?

3K20

【Java 基础 - 泛型机制详细解释】

为什么会引入泛型 泛型的本质是为了参数化类型(在不创建新的类型的情况下,通过泛型指定的不同类型来控制形参具体限制的类型)。...list.add(new Person()); 我们在使用上述list中,list中的元素都是Object类型(无法约束其中的类型),所以在取出集合元素时需要人为的强制类型转化到具体的目标类型,且很容易出现...当然,泛型方法不是仅仅可以有一个参数Class,可以根据需要添加其他参数。 为什么要使用泛型方法呢?...在调用泛型方法时,可以指定泛型,也可以不指定泛型: 在不指定泛型的情况下,泛型变量的类型为该方法中的几种类型的同一父类的最小级,直到Object 在指定泛型的情况下,该方法的几种类型必须是该泛型的实例的类型或者其子类...既然类型擦除了,如何保证我们只能使用泛型变量限定的类型呢? Java编译器是通过先检查代码中泛型的类型,然后在进行类型擦除,再进行编译。

53810
  • 三种骚操作绕过迭代器遍历时的数据修改异常

    导致这个报错出现的原因就和我们操作的一样,对于某些集合,不建议在遍历时进行数据修改,因为这样会数据出现不确定性。 那么如何绕过这个错误呢?这篇文章中脑洞大开的三种方式一定不会让你失望。...而上面与 modCount 进行对比的字段 expectedModCount 的值,其实是在创建迭代器时,从 modCount 获取的值。如果列表结构没有被修改过,那么两者的值应该是一致的。...可以看出来是先运行了迭代器 next 方法,然后才运行了System.out 进行输出。...所以第二种思路是先把第三个元素C++ 更新为Java ,然后启动一个线程,在迭代器再次调用 next 方法后,把第四个元素移除掉。这样就输出了我们想要的结果。...绕过方式三:利用类型擦除放入魔法对象 在创建集合的时候为了减少错误概率,我们会使用泛型限制放入的数据类型,其实呢,泛型限制的集合在运行时也是没有限制的,我们可以放入任何对象。

    59430

    Java泛型深入理解「建议收藏」

    我们在介绍泛型时指出向ArrayList中插入String类型的对象,编译时会报错。现在为什么又可以了呢?...泛型方法的类型推断 在调用泛型方法的时候,可以指定泛型类型,也可以不指定。 在不指定泛型类型的情况下,泛型类型为该方法中的几种参数类型的共同父类的最小级,直到Object。...编译器在编译时擦除了所有类型相关的信息,所以在运行时不存在任何类型相关的信息。例如List在运行时仅用一个List类型来表示。为什么要进行擦除呢?这是为了避免类型膨胀。 3....extends Number> list2=new ArrayList(); 假设前面的例子没有编译错误,如果我们把list1或者list2传入方法fillNumberList,显然都会出现类型不匹配的情况...如果说,T为Number的父类,我们想List中加入Number的子类肯定是可以的。 非法使用 对List进行迭代是不允许的。为什么呢?

    84020

    深入理解 Java 泛型

    > c = Lists.newArrayList(new Object()); Object o = c.get(0); c.add("12"); // 编译错误 为什么会编译报错呢?...我们可以将任意类型的集合赋值给List c变量。但是,add方法的参数类型是?,它表示未知类型,所以调用add方法时会编程错误,这是一种安全的做法。...而get方法返回集合中的元素,虽然集合中的元素类型未知,但是无论是什么类型,其均为Object类型,所以使用Object类型来接收是安全的。.../代码3,编译错误 } 代码3为什么会编译错误呢?...,在 add 时发现类型不一致立刻报错,而不是继续运行可能存在问题的程序 类型擦除(Type Erasure) 我们知道,编译器会将泛型擦除,那怎么理解泛型擦除呢?

    59430

    重学Java之泛型的基本使用

    幸运的是,一些bug更容易发现相对其他类型的bug,例如,编译时的bug可以在早期发现; 你可以使用编译器给出的错误信息来找出问题所在,然后在当时就解决它。...我一开始用的是JDK 8,在使用这个版本的时候,泛型已经进入Java十年了,泛型对于我来说是很理所当然的,就像鱼习惯了水一样。那Java为什么要引入泛型呢?...编译时进行更强的类型检查,编译器会对使用了泛型代码进行强类型检查,如果类型不安全,就会报错。编译时的错误会比运行时的错误,容易修复和查找。 Elimination of casts....这里来讲下我的理解,一般方法需要的参数,调用方没有提供,编译不通过。为什么泛型没有引入此设计呢,不传递类型参数,那不通过编译不是更好嘛。那让我们回忆一下,泛型是从JDK的哪个版本开始引入的?...总结一下Java为什么要引入泛型呢,原因大致有这么几个: 增强代码复用性、让错误在编译的时候就显现出来。

    37610

    第8章 泛型第8章 泛型

    如果依赖我们程序员自己去追踪对象类型和执行转换,那么运行时产生的错误将很难去定位和调试,然而有了泛型,编译器 可以帮助我们执行大量的类型检查,并且可以检测出更多的编译时错误。...(); numberList = integerList; // 编译错误:类型不兼容 编译器报错提示如下: ?...编译错误:类型不兼容 Java中泛型和数组的不同行为,的确引起了许多混乱。就算我们使用通配符,这样写: List类型)实例化的对象stack,src有 Iterable 与 Iterable,那么在调用pushAll方法时会发生type mismatch错误...同时去掉出现的类型声明,即去掉的内容。比如, T get() 就变成了Object get(), List 就变成了List。 最后,根据需要生成一些桥接方法。

    1.9K20

    详解 Java 泛型

    此时会发生什么情况呢?我们不能再向 list1 这个容器中 add 任何元素了!为什么呢。...因为编译器并不知道实际类型是什么(因为你给了编译器一个问号),所以你 add 任何类型的对象都会报类型不兼容的语法错误。有些小伙伴可能会问:把它当成 Object 类型的容器就好了啊!...抱歉,编译器不会这么做,除非在 “实在没有办法” 的情况,例: Object obj = list1.get(0); 为什么把调用 list1 的 get 方法叫 “实在没有办法” 的情况呢?...因为我在代码里面调用了 list1.get(0),这个方法是有返回值的,编译器必须给返回值给你,否则违反了 Java 的基本语法。...// 报类型不兼容错误 list.add(new A()); // 报类型不兼容错误 list.add(new B()); // 报类型不兼容错误 list.add(new C()); // 报类型不兼容错误

    93420

    Java 集合源码解析(1):Iterator

    Enumeration 接口早在 JDK 1.0 时就推出了,当时比较早的容器比如 Hashtable, Vector 都使用它作为遍历工具。 那 Enumeration 为什么会被废弃呢?...注意这个 [语法正确],事实上我们在使用 Iterator 对容器进行迭代时如果修改容器 可能会报 ConcurrentModificationException 的错。...fail-fast 与 ConcurrentModificationException 以 ArrayList 为例,在调用迭代器的 next,remove 方法时: public E next...不过意外的发现了,原来 for-each 的循环内部也是使用了 Iterator 来遍历Collection,它也调用了 Iterator.next(),所以在修改元素时会检查(元素的)变化并抛出 ConcurrentModificationException...差点忘了 Iterator 的使用 所有 Collection 的子类都有 iterator() 方法来获得 Iterator,通过 Iterator 的标准操作方法,可以让我们不必关心具体集合的类型,

    96450

    Python编程中的反模式

    为了照顾目标读者,本文做了一些简化(例如:在讨论迭代器的时候忽略了生成器和强大的迭代工具itertools)。 对于那些新手开发者,总有一些使用反模式的理由,我已经尝试在可能的地方给出了这些理由。...迭代 range的使用 Python编程新手喜欢使用range来实现简单的迭代,在迭代器的长度范围内来获取迭代器中的每一个元素: for i in range(len(alist)): print...那么什么值可以用来作为哨兵呢?在C语言时代或者更早,当int统治编程世界的时候,对于需要返回一个期望的错误结果的函数来说为通用的模式为返回-1。...为什么呢?在print_file函数里,当一个局部变量filename没有被找到时,下一步是在全局作用域中去寻找。...工厂函数可以显式生成list; [2] string.find(str)返回str在string中开始的索引值,如果不存在则返回-1; [3] 在外作用于中不要给函数中的局部变量名设置任何值,以防止函数内部调用局部变量时发生错误而调用外部作用域中的同名变量

    1.1K60

    深入理解 Java 泛型

    为什么引入泛型 在引入泛型之前,要想实现一个通用的、可以处理不同类型的方法,你需要使用 Object 作为属性和方法参数,比如这样: public class Generic { private...类型参数的意义是告诉编译器这个集合中要存放实例的类型,从而在添加其他类型时做出提示,在编译时就为类型安全做了保证。 这种参数类型可以用在类、接口和方法的创建中,分别称为泛型类、泛型接口、泛型方法。...> list, int i, int j){ Object o = list.get(i); list.set(j,o); } 这个代码看上去应该是正确的,但 Java 编译器会提示编译错误...编译器提示我们把方法中的 List 改成 List 就好了,这是为什么呢? ? 和 Object 不一样吗? 的确因为 ? 和 Object 不一样,List时强化它的类型信息,而在运行时丢弃(或者擦除)它的元素类型信息。擦除使得使用泛型的代码可以和没有使用泛型的代码随意互用。 3.如果类型参数在方法声明中只出现一次,可以用通配符代替它。

    2.2K111

    Iterator,fail-fast机制与比较器

    p=1185 迭代对于我们搞Java的来说绝对不陌生。我们常常使用JDK提供的迭代接口进行Java集合的迭代。...Iterator模式是用于遍历集合类的标准访问方法。 它可以把访问逻辑从不同类型的集合类中抽象出来,从而避免向客户端暴露集合的内部结构。 在没有迭代器时我们都是这么进行处理的。...next():返回迭代器刚越过的元素的引用,返回值是Object,需要强制转换成自己需要的类型 boolean hasNext():判断容器内是否还有可供访问的元素 void remove():删除迭代器刚越过的元素...所以要保证在遍历过程中不出错误,我们就应该保证在遍历过程中不会对集合产生结构上的修改(当然remove方法除外),出现了异常错误,我们就应该认真检查程序是否出错而不是catch后不做处理。...诚然,迭代器的快速失败行为无法得到保证,它不能保证一定会出现该错误,但是快速失败操作会尽最大努力抛出ConcurrentModificationException异常,所以因此,为提高此类操作的正确性而编写一个依赖于此异常的程序是错误的做法

    73820

    一文读懂《Effective Java》第23条:不要在新代码中使用原生态类型

    泛型出现后,我们通过泛型可以告诉编译器每个集合可以接受哪些对象类型,让编译器自动为集合的元素插入进行转化,并且在编译时告知我们是否插入了类型错误的对象。...泛型:编译期及早发现错误 使用泛型进行编码,有两个好处: 优点1:让编写代码时在编译期及早发现错误,并且助于定位报错位置 优点2:集合使用泛型,从集合中遍历元素时不需要再进行手工转换了(编译器替我们完成隐式转换...因此在代码开发时,我们不小心将一个coin 实例放进stamps集合时,编译器会及时提醒我们并产生一条编译错误信息,准确告知程序员哪里出现错误。...原生类型与泛型类型的区别 其一、使用原生态类型,会失掉泛型在安全性和其他表述性方面的优势。 为什么继续允许使用原生态类型呢?...泛型的不推荐使用场景 不要在新代码中使用原生态类型,这条规则有两个小小的例外,原因是:泛型信息可以在运行时被编译器擦除了。

    31120

    【Java基础】List集合系列

    extends E> c) // 3-返回list集合中指定索引位置的元素 E get(int index) // 4-返回list集合中第一次出现o对象的索引位置,如果list集合中没有o对象,那么就返回...-1 int indexOf(Object o) // 5-返回此列表元素的列表迭代器(按适当顺序) ListIterator listIterator() // 6-从指定位置开始,返回此列表元素的列表迭代器...AbstractList是一个抽象类,它也实现了List接口。 那为什么ArrayList继承它,而不是直接去实现List接口呢?...往上追溯,可以在Collections接口中的binarySearch()方法中会判断当前的List是否实现了RandomAccess接口,然后再决定使用for循环的还是使用迭代器的形式遍历当前List...transient关键字的作用是在序列化这个对象时,这个属性不会被序列化。 如果对ArrayList感兴趣可以查看我另一篇对ArrayList的详解,这篇文章的重心在介绍List集合。

    31110

    Java中泛型的详细解析,深入分析泛型的使用方式

    泛型的基本概念 泛型: 参数化类型 参数: 定义方法时有形参 调用方法时传递实参 参数化类型: 将类型由原来的具体的类型参数化,类似方法中的变量参数 类型定义成参数形式, 可以称为类型形参 在使用或者调用时传入具体的类型...,不能是简单类型 不能对确切的泛型类型使用instanceof操作,编译时会出错 泛型接口 泛型接口与泛型类的定义及使用基本相同 泛型接口常常被用在各种类的生产器中 示例: // 定义一个泛型接口 public...由此可见: 同一种泛型可以对应多个版本,因为参数类型是不确定的 不同版本的泛型类型实例是不兼容的 为了解决这样的问题,又不能为了定义一个新的方法来处理Generic,这与Java...key; } /* * 下面的这个方法显然是有问题的,在编译器中就会提示错误"cannot resolve symbol E" * 因为在类的声明中并未声明泛型E,所以在使用E...由于JVM的擦除机制,在运行时JVM是不知道泛型信息的: 所有可以给oa[1] 赋值一个ArrayList却不会出现异常 但是在取出数据的时候要做一次类型转换,就会出现ClassCastException

    1.1K10

    线性表及ArrayListLinkedList源码分析总结

    为什么我们啰里啰嗦的为两句代码解释了一堆内容呢?就是要强调,上面两个步骤顺序是不能颠倒的!为什么呢?...这说明——当使用Iterator迭代器进行迭代时,Iterator并不是把集合元素本身传递给了迭代变量,而是把集合元素的额值出给了迭代变量,因此我们在后边进行的各种赋值并不影响集合本身的元素。...而且子删除集合中元素时,我们优先考虑用Iterator的remve()方法,因为他有更高的效率,为什么呢?这里我们先作为一个遗留问题,后面我们再详细证明。   ...也就是说遍历ArrayList时,使用随机访问(即,通过索引序号访问)效率最高,这点毋庸置疑,使用迭代器遍历的效率最低(这点是网上的答案,由于两者的测试结果处于同一个数量级,加上机器误差,这点笔者很难证实...而言,list.get(i)方法是O(N)时间,慢在寻址;而他的remove()方法确实O(1)的。

    66340

    「源码分析」CopyOnWriteArrayList 中的隐藏知识,你Get了吗?

    get 方法也不例外,没错,就是这么粗暴。...,而在相等的情况下,依旧 setArray(elements); 这就很奇妙了,到底是为什么呢?...在拿到迭代器对象后,又添加了新元素 java ,可以看到遍历的结果没有报错也没有输出 java 。...也就是说拿到迭代器对象后,元素的更新不可见。 www.wdbyte.com 未读代码 这是为什么呢?要先从CopyOnWriteArrayList 的 iterator() 方法的实现看起。...可以看到在获取迭代器时,先 getArray() 拿到了数据数组 然后传入到 COWIterator 构造器中,接着赋值给了COWIterator 中的 snapshot 属性,结合上面的分析结果,可以知道每次更新都会产生新的数组

    86720

    Java集合详解3:一文读懂Iterator,fail-fast机制与比较器

    Iterator模式是用于遍历集合类的标准访问方法。 它可以把访问逻辑从不同类型的集合类中抽象出来,从而避免向客户端暴露集合的内部结构。 在没有迭代器时我们都是这么进行处理的。...迭代器与枚举有两点不同: 1、迭代器允许调用者利用定义良好的语义在迭代期间从迭代器所指向的 collection 移除元素。 2、方法名称得到了改进。...next():返回迭代器刚越过的元素的引用,返回值是Object,需要强制转换成自己需要的类型 boolean hasNext():判断容器内是否还有可供访问的元素 void remove():删除迭代器刚越过的元素...所以要保证在遍历过程中不出错误,我们就应该保证在遍历过程中不会对集合产生结构上的修改(当然remove方法除外),出现了异常错误,我们就应该认真检查程序是否出错而不是catch后不做处理。...诚然,迭代器的快速失败行为无法得到保证,它不能保证一定会出现该错误,但是快速失败操作会尽最大努力抛出ConcurrentModificationException异常,所以因此,为提高此类操作的正确性而编写一个依赖于此异常的程序是错误的做法

    94400

    Java Collection Framework : List

    换句话说,迭代器的快速失败行为仅用于检测代码的 bug。 本质: Fail-Fast 是 Java 集合的一种错误检测机制。...作用场景: 在使用迭代器时,Collection 的结构发生变化,抛出 ConcurrentModificationException 。...诚然,迭代器的快速失败行为无法得到保证,它不能保证一定会出现该错误,但是快速失败操作会尽最大努力抛出 ConcurrentModificationException 异常,所以,为提高此类操作的正确性而编写一个依赖于此异常的程序是错误的做法...为什么找到了元素就知道了index,不通过remove(index)来移除元素呢?...;    LinkedList 的 iterator 和 listIterator 方法返回的迭代器是快速失败的:在迭代器创建之后,如果从结构上对列表进行修改,除非通过迭代器自身的 remove

    92020

    List中remove()方法的陷阱,被坑惨了!

    因此从List.iterator()源码着手分析,跟踪iterator()方法,该方法返回了 Itr 迭代器对象。...,在 next、remove方法中都会调用checkForComodification 方法,该方法的 作用是判断 modCount !...所以用迭代删除元素是最保险的方法,建议大家使用List过程 中需要删除元素时,使用这种方式。学习资料:Java进阶视频资源 6、迭代遍历,用list.remove(i)方法删除元素--错误!!!...,原理同上述方法4. 7、List删除元素时,注意Integer类型和int类型的区别....2、List删除元素时,为避免陷阱,建议使用迭代器iterator的remove方式。 3、List删除元素时,默认按索引删除,而不是对象删除。 ---------- END ----------

    83230
    领券