CircularLinkedList<Integer>调用update方法歧义报错原因及修复方案
错误原因
报错的核心是方法重载歧义:
你在CircularLinkedList类中定义了两个参数数量相同的update重载方法:
update(E oldElement, E newElement):两个入参都是泛型类型update(E e, int index):第一个入参是泛型类型,第二个是基础类型int
当你实例化CircularLinkedList<Integer>,调用update(20,25)时,编译器无法判断匹配哪个方法:
- 两个入参
20、25都可以自动装箱为Integer,匹配第一个重载 - 第一个入参
20自动装箱为Integer,第二个入参25可以保留为int类型,也匹配第二个重载
编译器没有优先级规则判定选哪个,就会抛出method ambiguous错误。
修复方案
方案1:修改方法名消除重载(推荐)
从根源避免歧义,同时提升代码可读性,将两个方法按功能重命名:
// 按旧元素值替换为新元素 public void updateByElement(E oldElement, E newElement) { // 原有逻辑 } // 按下标位置更新元素 public void updateByIndex(E newElement, int index) { // 原有逻辑 }
调用时直接对应方法名即可:
ccl.updateByElement(20, 25);
方案2:调用时显式指定参数类型(临时解决)
如果不想修改方法定义,调用时主动将两个入参都声明为Integer类型,告诉编译器匹配第一个重载:
ccl.update(Integer.valueOf(20), Integer.valueOf(25));
附加代码优化建议
- 引用类型值比较不要用
==/!=:你现有update方法中用temp.getElement() != oldElement比较Integer对象,Integer缓存范围仅在-128~127之间,超出范围的数值会生成新对象,直接比较地址会出现匹配失败的问题,建议改为Objects.equals()比较,同时增加遍历边界判断避免死循环:
public void updateByElement(E oldElement, E newElement) { if (size == 0) { throw new RuntimeException("列表为空,无法更新元素"); } Node<E> temp = head; for (int i = 0; i < size; i++) { if (Objects.equals(temp.getElement(), oldElement)) { temp.setElement(newElement); return; } temp = temp.next; } throw new RuntimeException("列表中未找到待更新的元素"); }
- 下标更新方法的定位逻辑有误:原有
update(E e, int index)方法中循环到(index-1)%size会定位到目标下标的前一个节点,修改的是前一个节点的值,建议调整为直接定位到目标下标节点:
public void updateByIndex(E newElement, int index) { if (size == 0) { throw new RuntimeException("列表为空,无法更新元素"); } int realIndex = index % size; Node<E> temp = head; for (int i = 0; i < realIndex; i++) { temp = temp.next; } temp.setElement(newElement); }
内容的提问来源于stack exchange,提问作者user13278163
相关产品推荐
相关产品推荐

