You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

调用其他类Getter获取ArrayList元素失败,报空指针异常求助

解决你的Java代码问题:空指针异常与字符串匹配失效

我来帮你拆解代码里的核心问题,这两个点就是导致你遇到异常、判断逻辑不执行的根源:

1. 字符串比较用==而非equals(),导致匹配失败

你在getPrice方法里的判断逻辑用了==比较字符串:

if(shoppingList.get(i).getItemName() == itemName)

在Java里,==比较的是对象的内存引用地址,而不是字符串的实际内容。哪怕两个字符串内容完全一样,只要不是同一个对象实例,==就会返回false。

另外,你的ShopItems构造函数里把传入的itemName转成了全大写:

itemName = i.toUpperCase();

但你查询时传的是"Pens"(首字母大写),存储的却是"PENS"(全大写),这也会直接导致匹配不上。

修复方案:
改用equals()比较内容,同时统一大小写避免匹配偏差:

// 把查询的名称也转成大写,和存储的格式统一
if(shoppingList.get(i).getItemName().equals(itemName.toUpperCase()))

如果担心传入的itemName为null引发空指针,可以反过来写更安全:

if(itemName.toUpperCase().equals(shoppingList.get(i).getItemName()))

2. 空指针异常的几个潜在来源

(1)ShopItems的setPrice方法参数缺失类型

你的setPrice方法有语法错误,参数p没声明类型:

private void setPrice(p){ price = Math.abs(p); }

必须补全参数类型,否则编译都通不过,间接引发运行时异常:

private void setPrice(double p){ price = Math.abs(p); }

(2)ShopLedger构造函数的冗余代码

你写的构造函数里,new ArrayList<>(s)已经把原列表的元素拷贝到shoppingList里了,后面的循环完全是多余的——相当于把刚拷贝的元素又重新赋值一遍,没有任何意义。如果原列表s里存在null元素,shoppingList里也会有null,遍历调用getItemName()时就会抛出空指针。

另外你注释里提到要做深拷贝,当前的浅拷贝只是拷贝了对象引用,修改原列表的元素会影响shoppingList。如果需要真正的深拷贝,应该创建新的ShopItems对象:

public ShopLedger(ArrayList<ShopItems> s){
    shoppingList = new ArrayList<>();
    for(ShopItems item : s){
        // 跳过null元素,避免后续遍历空指针
        if(item != null){
            shoppingList.add(new ShopItems(item.getItemName(), item.getPrice()));
        }
    }
}

(3)客户端初始化的潜在问题

确保你客户端初始化shoppingList时,每个元素都是有效的ShopItems对象,没有null。比如正确的初始化方式:

ArrayList<ShopItems> items = new ArrayList<>();
items.add(new ShopItems("Candy", 2.3));
items.add(new ShopItems("Book", 20.0));
items.add(new ShopItems("Pens", 5.5));
items.add(new ShopItems("Tape", 10.2));
ShopLedger ledger = new ShopLedger(items);

最终修复后的关键代码

修改后的ShopItems类

public class ShopItems {
    private String itemName;
    private double price;

    public double getPrice(){
        return price;
    }

    public String getItemName(){
        return itemName;
    }

    // 补全参数类型
    private void setPrice(double p){
        price = Math.abs(p);
    }

    public ShopItems(String i, double p){
        itemName = i.toUpperCase();
        setPrice(p);
    }
}

修改后的ShopLedger类

import java.util.ArrayList;

public class ShopLedger {
    private ArrayList<ShopItems> shoppingList;

    // 实现深拷贝+避免null元素
    public ShopLedger(ArrayList<ShopItems> s){
        shoppingList = new ArrayList<>();
        for(ShopItems item : s){
            if(item != null){
                shoppingList.add(new ShopItems(item.getItemName(), item.getPrice()));
            }
        }
    }

    public Double getPrice(String itemName) {
        // 提前处理null参数
        if(itemName == null){
            return null;
        }
        String targetName = itemName.toUpperCase();
        for(ShopItems item : shoppingList){
            // 避免item为null引发空指针
            if(item != null && targetName.equals(item.getItemName())){
                return item.getPrice();
            }
        }
        return null;
    }
}

这样修改后,查询"Pens"时会自动转成"PENS"和存储的名称匹配,同时彻底避免了空指针异常,也实现了你想要的深拷贝效果。

内容的提问来源于stack exchange,提问作者lettuce

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 09:43:44