-2

这是我的代码:

不包括 Getter、Setter 和导入

零件类:

public class Part{
    private String name;
    private String id;
    private int quantity;
    private BigDecimal purchaseprice;
    private BigDecimal saleprice;
    private ArrayList<String> subparts;
    private String description;

    public Part(String File, String ID)
    {
        Part TempP = DataAccess.getPart(File, ID);
        this.name = TempP.name;
        this.id = TempP.id;
        this.quantity = TempP.quantity;
        this.purchaseprice = TempP.purchaseprice;
        this.saleprice = TempP.saleprice;
        this.subparts = TempP.subparts;
        this.description = TempP.description;
    }

    public Part(){}

    public Part(String name, String id, int quantity, BigDecimal purchaseprice,
            BigDecimal saleprice, ArrayList<String> subparts, String description) {
        this.name = name;
        this.id = id;
        this.quantity = quantity;
        this.purchaseprice = purchaseprice;
        this.saleprice = saleprice;
        this.subparts = subparts;
        this.description = description;
    }

数据访问类:

public class DataAccess
{    
    public static ArrayList<Part> getAllParts(String aFile){
        ArrayList<Part> PartList = new ArrayList<Part>();
        try{
            BufferedReader fin = new BufferedReader(new FileReader(aFile));
            while(true){
                String TempS[];
                TempS = fin.readLine().split(",");
                if(TempS[0] == null){break;}
                ArrayList<String> subparts = new ArrayList<String>();
                for(int i = 6; i < TempS.length; i++){
                    subparts.add(TempS[i]);
                }
                PartList.add(new Part(TempS[1], TempS[0],Integer.valueOf(TempS[2]),BigDecimal.valueOf(Double.valueOf(TempS[3])),BigDecimal.valueOf(Double.valueOf(TempS[4])),subparts,TempS[5]));
            }
            fin.close();
            return PartList;
        }catch(FileNotFoundException ex)
        {
            return PartList;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return PartList;
    }

所以问题是它按计划完美执行,直到它命中PartList.add(new Part(TempS[1], TempS[0],Integer.valueOf(TempS[2]),BigDecimal.valueOf(Double.valueOf(TempS[3])),BigDecimal.valueOf(Double.valueOf(TempS[4])),subparts,TempS[5]));然后它抛出一个ClassNotFoundException,我已经通过eclipse调试器完全跟踪它并且所有数据都是正确的......有人可以告诉我我做错了什么吗?以及对我的代码的任何其他建议也将不胜感激......

Exception in thread "main" java.lang.NullPointerException
    at DataAccess.getAllParts(DataAccess.java:42)
    at MainController.SummonParts(MainController.java:38)
    at MainController.main(MainController.java:11)

调试器在崩溃之前读取第 48 行的 ClassNotFound 错误...

4

3 回答 3

1
ArrayList<Part> PartList = null;

进而

PartList.add(...);

导致NPE -NullPointerException

编辑

我建议你把你的while循环改成这样:

    String line;           
    while((line=fin.readLine()) != null){
        String[] TempS = line.split(",");
        ArrayList<String> subparts = new ArrayList<String>();
        for(int i = 6; i < TempS.length; i++){
            subparts.add(TempS[i]);
        }
        PartList.add(new Part(TempS[1], TempS[0],Integer.valueOf(TempS[2]),BigDecimal.valueOf(Double.valueOf(TempS[3])),BigDecimal.valueOf(Double.valueOf(TempS[4])),subparts,TempS[5]));
    }

请注意,我只是在展示逻辑。您仍然可能有其他错误。

于 2013-05-17T02:57:43.280 回答
0
  • 6一个幻数;用符号常量替换它。事实上,对 , 等做同样的0事情1
  • 您仍然没有遵循 Java 命名约定:
    • 变量是驼峰式的。
    • 类是大写的和驼峰式的。
    • 枚举是 ALL_CAPS_WITH_UNDERSCORES。
  • 你的名字应该更具体。TempS并且DataAccess对他们处理的对象类型只字不提。
    • 也许PartDAO代替DataAccess.
    • 也许partData代替TempS.
  • 而且,请不要过多地使用静力学。让您的main方法初始化一个对象并告诉它完成工作。这样,您可以将您的方法拆分为可以测试的较小的方法。
  • 以块的形式关闭您的流finally或使用 Java 7 try-with-resources。
  • FileNotFoundException不应忽略,只返回一个空列表。
  • 更喜欢日志系统而不是e.printStackTrace(). 看logback
  • 不要将变量声明为ArrayLists; 改为编程到接口并使其成为Lists。
  • 格式化你的代码,这样你就不会超过第 80 列左右。
  • BufferedReader.readLine()null在文件末尾返回。因此,程序到达文件末尾,它调用null.split(",").
  • 您是否有机会处理包含转义的 csv 文件,因为项目中包含逗号或引号?查看 csv 库。
  • BigDecimal.valueOf(Double.valueOf(TempS[3]))太复杂了。事实上,BigDecimal有一个构造函数接受 a String,这是首选使用的构造函数。所以,new BigDecimal(TempS[3])比较好。另一方面,文件是否有可能包含$19.38在其中而不是19.38? 你可能想看看MessageFormat
于 2013-05-17T03:23:46.810 回答
0

我突然想到的一件事是,您依靠内部 if 条件来打破循环。取而代之的是,您可以将测试用作while循环的一部分,例如

BufferedReader fin = new BufferedReader(new FileReader(aFile));
String line = fin.readLine();
while (line != null) {
  //execute code here
  line = fin.readLine();
}

这更好,因为您不必担心在循环内使用空值,并且可以摆脱 while 循环内的 break 语句。

另外,您确定在 import 语句中有BufferedReader,FileReader和classes 吗?Part如果你不能创建一个新的Part,那将在该行中抛出一个 NPE。

要测试您是否可以访问该Part对象:

Part newPart = new Part(/*add all constructor args*/);
if (newPart != null) {
  System.out.println("Non-null Part");
  partList.add(newPart);
}

如果您获得控制台输出,则部件对象已添加到列表中。如果没有,那就是你的错误所在。

于 2013-05-17T03:32:44.290 回答