如何正确抛出异常

时间:2013-05-26 02:28:43

标签: java exception-handling

我正在尝试将数据从二进制文件读入二维数组,同时整理出最大数据点之上的任何负数或值(在int []中)。我可以在没有例外的情况下正确填充数组,但是需要为超出可接受范围的数据抛出异常。当我添加异常时,数组永远不会填充第一行。任何见解都会非常感激。

public class DataExceedsMaxDataPoint extends Exception {
    public DataExceedsMaxDataPoint() {
        super("Error: Data Exceeds Maximum Data Point");
    }

    public DataExceedsMaxDataPoint(int number, int maxData) {
        super("Error: Data(" + number + ") Exceeds Maximum Data Point(" +
                maxData + ")");
    }
}

public class NegativeData extends Exception {
    public NegativeData() {
        super("Error: NegativeData Not Allowed");
    }

    public NegativeData(int number) {
        super("Error: Negative Data(" + number + ") Not Allowed");
    }
}

import java.io.*;

public class ChemExpDataValidation2 {
    public static void main(String[] args) throws IOException {
        int[] dataMax = {35, 55, 72, 75, 45, 100}; //max data points
        int[][] chemData = new int[6][10];
        int number;
        int maxData;
        boolean endOfFile = false;

        FileInputStream fstream = new FileInputStream("data.dat");
        DataInputStream inputFile = new DataInputStream(fstream);

        System.out.println("Reading numbers from the file:");

        while (!endOfFile) {
            try {
                for (int row = 0; row < 6; row++) {
                    maxData = dataMax[row];
                    for (int col = 0; col < 10; col++) {
                        number = inputFile.readInt();
                        if (number <= maxData && number > 0) {
                            chemData[row][col] = number;
                        }
                        if (number > maxData) {
                            throw new DataExceedsMaxDataPoint(number, maxData);
                        }
                        if (number < 0) {
                            throw new NegativeData(number);
                        }
                    }
                }
                for (int row = 0; row < 6; row++) {
                    for (int col = 0; col < 10; col++) {
                        System.out.printf("%4d", chemData[row][col]);
                    }
                    System.out.printf("\n");
                }
            } catch (DataExceedsMaxDataPoint e) {
                System.out.println(e.getMessage());
                continue;
            } catch (NegativeData e) {
                System.out.println(e.getMessage());
                continue;
            } catch (EOFException e) {
                endOfFile = true;
            }

        }
        inputFile.close();
        System.out.println("\nDone.");
    }
}

4 个答案:

答案 0 :(得分:1)

您的要求没有意义。异常基本上取消了try块正在执行的操作。如果正确构造并与捕获区中的适当动作相匹配,理想情况下,操作应该完全恢复进入试验之前存在的条件。

答案 1 :(得分:1)

尝试/ catch块起初非常令人困惑,至少对我来说是这样。但我喜欢看它们是尝试这个,如果它不起作用不要崩溃程序但跛行到终点线(或尝试使用新变量,看看是否有效)。

try{
    someMethod(); // some method that could result in a crash of the program but want to try it
                 //if it works great but if not here is why but didn't blow up 
    Object = someOtherObject; // for example could be null, and throw an error but you want to try it first
}catch(Exception e){
    displayMessage(); // inform the user that the process couldn't go through 
                      //could also send yourself a copy of the stack trace 
}

该计划将继续进行,因为它“试图”这样做,但只是没有工作,但能够回去。

当你说你可以让它填充而没有好的例外,这意味着你的逻辑运行良好。我只想把它全部放在1次尝试/捕获中,如果它失败了它会抓住它。保持简单:)

希望这有助于或指出正确的方向。

答案 2 :(得分:0)

如果无效记录确实符合例外条件,则抛出异常,并且没有其他“结果”。这实际上意味着无法从中恢复,继续执行此任务是没有意义的(这是Scala建议使用异常的方式)。

如果要忽略无效记录,则不需要例外。 如果要返回无效记录列表,请将成功记录和无效记录列表放在一个类中,然后返回此记录。

一般来说,在导入数据时(尤其是从普通文件中导入数据),我通常根本不使用任何异常,因为它存在验证问题。因此,如果您提供完整的无效记录列表而不是在第一次错误后立即抛出一个异常,用户会很高兴。

因此,有时“如何正确抛出异常”的答案只是“不要乱扔”。<​​/ p>

答案 3 :(得分:0)

首先,你的投注没有多大意义。当出现异常行为时,您应抛出异常,并且调用方法应负责处理它。在这里,你们都期待错误并将其捕获到相同的方法块中,而方法块的流动方式不同。

简单地说,exceptions break the natural flow of the program.如果任何块中出现Throwable,则暂停执行该特定块,并且只有catch / finally条件为处理。您的问题 - 数据不会在第一行之后填充 - 受此影响;被认为是“特殊”的东西导致持续的循环停止。

你有几个选择:

  • 不要与异常作斗争。他们正在按预期工作 - 如果在进入时发生某种异常状态,您所说的是您不希望代码继续超过这一点。用外行人的话说,传递有效数据。

  • 不要使用例外。如果您想忽略无效数据,那么首先没有理由让它们出现。

  • 将异常列入可能的最窄范围。您可以在读取int之后放置try...catch块。更好的是,将它写为一个声明其检查抛出的单独方法,并将其命名为:

    public static int checkValidInput(int number, int maxData)
            throws DataExceedsMaxDataPoint, NegativeData {
        if (number > maxData) {
            throw new DataExceedsMaxDataPoint(number, maxData);
        } else if (number < 0) {
            throw new NegativeData(number);
        } else {
             return number;
        }
    }
    

    for (int row = 0; row < 6; row++) {
        maxData = dataMax[row];
        for (int col = 0; col < 10; col++) {
            try {
                number = checkValidInput(inputFile.readInt(), maxData);
            } catch (DataExceedsMaxDataPoint e) {
                System.out.println(e.getMessage());
            } catch (NegativeData e) {
                System.out.println(e.getMessage());
            } catch (IOException e) { // generify the EOFException instead
                endOfFile = true;
            } 
        }
    }