【问题标题】:Throws Exception Error in Java在 Java 中引发异常错误
【发布时间】:2014-07-23 02:38:41
【问题描述】:

我正在开发一种库存程序,该程序处理从文件中读取项目列表,但遇到了一些麻烦。

这是我到目前为止完成的代码:

import java.util.Scanner; 
import java.io.*; 

public class Store { 
    public static void main(String[] args) throws Exception {
        Book[] books = readInventory();

        for (Book book : books) {
            System.out.printf("ISBN: %s, Price: %f, Copies: %d%n",
            book.getISBN(), book.getPrice(), book.getCopies()); 
        }
    }

    public static Book[] readInventory() throws Exception {
        Book[] books = new Book[15];
        java.io.File file = new java.io.File("../instr/prog4.dat");
        Scanner fin = new Scanner(file);
        String isbn;
        double price;
        int copies;
        int i = 0;

        while (fin.hasNext()) {
             isbn = fin.next();
                if (fin.hasNextDouble()); {
                    price = fin.nextDouble();
                }
                if (fin.hasNextInt()); {
                    copies = fin.nextInt();
                }
             Book book = new Book(isbn, price, copies);
             books[i] = book;
             i++;
        }
        fin.close();
        return books;
}

    public static void printInfo(Book[] books) {
        for(int x=0; x<books.length; x++) {
            System.out.println("ISBN: " + books[x].getISBN() + "\n Price: " +
            books[x].getPrice() + "\n Copies: " + books[x].getCopies());
        }   
    }
}

class Book {
    private String isbn;
    private double price;
    private int copies;

    public Book(String isbnNum, double priceOfBook, int copiesInStock) {
        isbn = isbnNum;
        price = priceOfBook;    
        copies = copiesInStock;
    }

    public String getISBN() {
        return isbn;
    }

    public double getPrice() {
        return price;
    }

    public int getCopies() {
        return copies;
    }

    public void setISBN(String isbn) {
        this.isbn = isbn;
    }

    public void setPrice(double price) {
        this.price = price;
    }

    public void setCopies(int copies) {
        this.copies = copies;
    }

    @Override
    public String toString() {
        return String.format("ISBN: %s, Price: %f, Copies: %d%n",
             this.getISBN(), this.getPrice(), this.getCopies());
    }
}

程序可以正常编译,但是当我运行程序时出现错误

Exception in thread "main" java.util.NoSuchElementException
    at java.util.Scanner.throwFor(Scanner.java:855)
    at java.util.Scanner.next(Scanner.java:1364)
    at Store.readInventory(Store.java:31)
    at Store.main(Store.java:13)

这是我应该使用的文件的内容:

1234567 31.67 0
1234444 98.50 4
1235555 27.89 2
1235566 102.39 6
1240000 75.65 4
1247761 19.95 12
1248898 155.91 0
1356114 6.95 17
1698304 45.95 3
281982X 31.90 5

我一直在查看我最近编写的另一个程序,该程序处理读取文件,看看我在相同类型的地方抛出异常,看起来我是(在该程序中处理文件的所有内容都在main 方法,所以这是唯一一个抛出异常的方法)。根据我对早期 Java 编程类的记忆,我们应该在 main 方法和任何其他处理文件的方法中抛出异常,所以在这种情况下,我在 main 方法上设置了一个,在 readInventory() 方法上设置了另一个。

我错过了什么?

【问题讨论】:

  • 您正在检查fin.hasNext(),它告诉您文件中至少还剩下 一个 东西,但是您假设文件中有 15 本书。您的文件是否真的包含您要读取的所有数据?
  • 部分说明是创建一个 Book 类型的数组,该数组最多可容纳 15 个书籍对象,但该文件实际上只包含 10 行(每行包含 ISBN、价格和金额有货)。

标签: java file exception


【解决方案1】:

在阅读之前检查下一个值以避免像您对 isbn 所做的那样的异常,而不是 pricecopies

示例代码:

 if(fin.hasNextDouble()){
      price = fin.nextDouble();
 }
 if(fin.hashNextInt()){
     copies = fin.nextInt();
 }

例如Scanner#nextInt() 方法抛出:

  • InputMismatchException - 如果下一个标记与整数正则表达式不匹配,或者超出范围
  • NoSuchElementException - 如果输入用尽
  • IllegalStateException - 如果此扫描仪已关闭

您正在创建大小为 15 的数组,其中文件中只有 10 行导致 NullPointerException。在这种情况下使用List

即使出现错误,您也可以使用Java 7 - The try-with-resources Statement 进行更好的资源管理。

示例代码

public static BookDetail[] readInventory() throws Exception {
    List<BookDetail> books = new ArrayList<BookDetail>();
    java.io.File file = new java.io.File("../instr/prog4.dat");
    try (Scanner fin = new Scanner(file)) {
        String isbn;
        double price = 0;
        int copies = 0;
        while (fin.hasNext()) {
            isbn = fin.next();
            if (fin.hasNextDouble()) {
                price = fin.nextDouble();
            }
            if (fin.hasNextInt()) {
                copies = fin.nextInt();
            }
            BookDetail book = new BookDetail(isbn, price, copies);
            books.add(book);
        }
    }
    return books.toArray(new BookDetail[books.size()]);
}

【讨论】:

  • 谢谢,这很有意义。只是想弄清楚这应该在我的代码中的确切位置以及需要删除哪些内容以减少任何冗余?
  • 仍在努力尝试实现此代码。我遇到的错误之一是“没有'catch'或'finally'的'try'”我试图阅读并找出将catch或finally放在哪里,但我一直收到同样的错误。跨度>
  • 我的 printInfor 方法也出现了几个错误“Store.java:72: 表达式的非法开始 public void printInfo(Book[] books) { ^ Store.java:72: 非法开始表达式 public void printInfo(Book[] books) { ^ Store.java:72: ';'预期的公共无效打印信息(书籍 [] 书籍){ ^ Store.java:72: ';'预期的公共无效 printInfo(Book[] books) {"
  • 这是编译器错误?你在使用任何 IDE 吗?如果没有,请使用它。
  • 是的,这些是编译器错误。我目前没有,因为我们的教授让我们使用 UNIX 系统,但我可以尝试一下。我只需要将文件从 No Machine(远程 UNIX 登录)转移到我的 PC
【解决方案2】:

目前,您正在检查文件是否有更多数据,然后您尝试阅读 15 本书,无论如何。您的 for 循环从 0 变为 books.length-1,无论文件中的内容是什么。

由于您不知道(理论上)文件中有多少本书,因此您需要在阅读每本书之前检查fin.hasNext

所以摆脱你的 for 循环并用类似这样的东西替换你的阅读代码:

int i = 0;
while (fin.hasNext()) {
     // read book here and assign to books[i]

     // increment i for next iteration
     i++;
}

在阅读每本书之前会检查while条件fin.hasNext()。当它返回 false 时,您将停止循环,i 将是您阅读的书数。

请注意,您仍然假设每本书都有其所有字段。如果文件中只有半本书,您的代码仍然会崩溃。但这可能是件好事,因为没有真正的方法可以从中恢复,并且大概您可以假设您只会收到格式正确的输入。

【讨论】:

    【解决方案3】:

    我建议您使用异常处理。我特别建议对资源使用 try,因为您忘记关闭正在使用的扫描仪。

    您需要签入您收到每本书所需的所有信息的代码。您不希望仅仅因为您无法收到关于该特定图书的其余数据而仅获得该图书的部分信息。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-01-08
      • 2014-08-11
      • 1970-01-01
      • 1970-01-01
      • 2013-03-01
      • 2018-03-21
      • 2012-11-18
      相关资源
      最近更新 更多