使用@FindBy注解时List移除元素后大小仍为3的问题求助
这是因为PageFactory生成的List
1. PageFactory代理列表的特性
当你用@FindBy注解声明List<WebElement>时,PageFactory并不会立刻去DOM中查询元素并生成一个固定大小的集合。它会创建一个动态代理列表,每次你调用size()、get()这类方法时,代理都会重新执行一遍你的xpath表达式//th,去DOM中实时获取当前符合条件的元素数量和内容。
在你的代码里,columns.remove(i)只是临时移除了代理列表中的一个元素引用,但这个操作既不会改变DOM中的实际元素,也不会影响代理列表后续的查询逻辑。所以当你再次调用columns.size()时,它又重新查询了一遍DOM,发现还是3个<th>元素,自然返回大小为3。
2. 手动创建List的行为
如果是通过driver.findElements(By.xpath("//th"))手动获取的List,这是一个普通的ArrayList快照——它会在调用方法时一次性把DOM中符合条件的元素全部取出来,存储在内存里。后续你对这个List的移除操作,都是直接修改内存中的集合,不会再去DOM重新查询,所以集合大小会正确显示为2。
解决办法
方案1:将代理列表转为普通集合
在操作前,把PageFactory生成的代理列表转成普通ArrayList,这样就变成了固定的快照,后续操作都基于内存中的集合,不会再触发DOM查询:
public List<WebElement> getColumns() { // 转成普通ArrayList,脱离代理逻辑 List<WebElement> actualColumns = new ArrayList<>(columns); System.out.println("Initial columns list size " + actualColumns.size()); for (int i = 0; i < actualColumns.size(); i++) { System.out.println(actualColumns.get(i).getText()); if (actualColumns.get(i).getText().equals("Instructor")) { actualColumns.remove(i); // 移除元素后要i--,避免跳过下一个元素 i--; } } System.out.println("After modification column list size " + actualColumns.size()); return actualColumns; }
方案2:避免直接操作PageFactory生成的List
不要直接修改@FindBy注解的List对象,而是每次需要时手动执行查询,或者先转为普通集合再进行增删操作。
另外提醒一句:你代码里的循环移除元素逻辑有个小问题——移除元素后如果不执行i--,会导致循环跳过下一个元素,这个是Java集合操作的常见坑,注意规避~
内容的提问来源于stack exchange,提问作者Blue Star

