简体   繁体   English

抓到try-catch块错误后继续执行

[英]Continue the execution after catching the error in try-catch block

After catching an exception, how do I continue the execution of a Java program?捕获异常后,如何继续执行Java程序?

So I made a program to insert or delete nodes from specific positions in Doubly Linked List.所以我做了一个程序来从双向链表的特定位置插入或删除节点。 Those 2 methods throw exception.这两种方法抛出异常。

In main method, I have started to insert some int values to positions.在 main 方法中,我已经开始向位置插入一些 int 值。 If I entered wrong pos value insert method throws an error and catch block handle.如果我输入了错误的 pos 值,插入方法会抛出错误并捕获块句柄。

  1. If I have entered 30 nodes and insert them to the correct positions except 1 Node.如果我输入了 30 个节点并将它们插入正确的位置,除了 1 个节点。 -After false entry (ie in the middle of the insertions) how can I continue to insert the rest? - 错误输入后(即在插入中间)如何继续插入 rest?
    public static void main(String[] args) {
        LinkedList myList = new LinkedList();
        try {
            myList.Insert(1, 0);
            myList.Insert(5, 54); //  this is the false entry
            myList.Insert(1, 0);
            myList.Insert(1, 0);
        
        } catch (Exception ex) {
            System.out.println(ex.toString());
        }
        myList.Out();
        myList.ReverseOutput();     

      }

    }

So after execution, the output is 1. How can I make it [1 , 1 , 1]?

You can wrap myList.insert in a method which ignores the Exception, and use that instead:您可以将myList.insert包装在忽略异常的方法中,然后改用它:

static void insertAndIgnoreException(LinkedList list, int position, int value) {
  try {
    list.Insert(position, value);
  } catch (LinkedListInsertionException e) {
    System.out.println(e.getMessage());
  }
}

So your main becomes:所以你的主要变成:

public static void main(String[] args) {
        LinkedList myList = new LinkedList();
        insertAndIgnoreException(1, 0);
        insertAndIgnoreException(5, 54); //  this is the false entry
        insertAndIgnoreException(1, 0);
        insertAndIgnoreException(1, 0);

        myList.Out();
        myList.ReverseOutput();     

  }

Some notes:一些注意事项:

  1. I've used a specific exception type LinkedListInsertionException .我使用了特定的异常类型LinkedListInsertionException Never catch and ignore Exception , as you'll end up missing all sort of other problems, eg NullPointerException s.永远不要捕获并忽略Exception ,因为您最终会错过所有其他问题,例如NullPointerException
  2. Stick to Java naming conventions in your code.在代码中坚持 Java 命名约定。 ie insert not Insert .insertInsert
  3. Don't reuse JDK class names, ie use MyLinkedList not LinkedList .不要重复使用 JDK class 名称,即使用MyLinkedList而不是LinkedList

In this example, you can solve this by using a loop .在此示例中,您可以使用循环来解决此问题。

Something like:就像是:

int[] numsToInsert = new int[] {1, 0, 5, 54, 1, 0, 1, 0};

for(int i = 0; i < 8; i += 2){
    try {
        myList.Insert(numsToInsert[i], numsToInsert[i + 1]);
    } catch (Exception ex) {
        System.out.println(ex.toString());
    }
}

This will catch the exception separately for each insertion by performing the insertions iteratively.这将通过迭代执行插入来分别捕获每次插入的异常。

The short answer is: you don't.简短的回答是:你不知道。

... but that doesn't mean there is nothing you can do. ...但这并不意味着您无能为力。

The purpose to a try/catch is stop all processing once an error is detected. try/catch 的目的是在检测到错误后停止所有处理。 Its purpose is to skip the rest of the code (through to the catch).它的目的是跳过代码的 rest(一直到捕获)。 It's doing exactly what it is supposed to do, it is the same as saying "skip me".它正在做它应该做的事情,就像说“跳过我”一样。

So your question "how do I run the rest of the code" can only be acheived by removing the code from "skip me" instruction.所以你的问题“我如何运行代码的 rest”只能通过从“跳过我”指令中删除代码来实现。

        try {
            myList.Insert(1, 0);
            myList.Insert(5, 54); //  this is the false entry
        
        } catch (Exception ex) {
            System.out.println(ex.toString());
        }
        myList.Insert(1, 0);
        myList.Insert(1, 0);
        myList.Out();
        myList.ReverseOutput();   

This will give you the output you expect.这将为您提供您期望的 output。

... but it doesn't feel quite right ……但感觉不太对

If we are removing code from the try it almost seems like the try isn't worth having.如果我们从try中删除代码,那么 try 似乎不值得拥有。 The thing is, that try block was put there there for some reason.问题是,那个 try 块出于某种原因被放在那里。 Try blocks are supposed to catch errors and it successfully did so, so obviously its doing something useful, and taking the code out of it feels like the wrong solution. Try 块应该捕获错误并且它成功地做到了,所以显然它做了一些有用的事情,并且从中取出代码感觉像是错误的解决方案。

What we want is for each one of the lines of code to be tried, and if it fails, try the next one.我们想要的是每一行代码都要试,如果失败了,再试下一行。 Notice I said try more than once, and also "each one "注意我说try不止一次,还有“每一个

        try {
            myList.Insert(1, 0);
        } catch (Exception ex) {
            System.out.println(ex.toString());
        }
        try {
            myList.Insert(5, 54); //  this is the false entry
        } catch (Exception ex) {
            System.out.println(ex.toString());
        }
        try {
            myList.Insert(1, 0);
        } catch (Exception ex) {
            System.out.println(ex.toString());
        }
        try {
            myList.Insert(1, 0);
        } catch (Exception ex) {
            System.out.println(ex.toString());
        }

This will also give you the output you want, and also handles any of those inserts kicking out an error.这还将为您提供所需的 output,并处理任何引发错误的插入。

... but it doesn't feel quite right ……但感觉不太对

That's a lot of repetitive text, just to do the same insert over and over.那是很多重复的文本,只是为了一遍又一遍地做同样的插入。 If only we had a way to repeat things?如果我们有办法重复事情就好了?

int values[4][2] = {
    {1,0},
    {5,54},
    {1,0},
    {1,0}
};

for(int v[2] : values){
    try {
        myList.Insert(v[0], v[1]);
    } catch (Exception ex) {
        System.out.println(ex.toString());
    }
}

This will give you the output you want, handles any of the inserts kicking out an error, and avoids the constant repetition.这将为您提供所需的 output,处理任何引发错误的插入,并避免不断重复。

... but it doesn't feel quite right ……但感觉不太对

There was no loop being used for that original code.该原始代码没有使用循环。 I assume that was for a reason: possibly it was a test stub that will eventually be receiving values from somewhere else.我认为这是有原因的:可能它是一个测试存根,最终将从其他地方接收值。

This indicates that having each item tested independantly is the actual purpose of this code.这表明独立测试每个项目是此代码的实际目的 If so, there is a way that we could have the single line of code handle its own error:如果是这样,有一种方法可以让单行代码处理它自己的错误:

function TryInsert(list,pos,val){
    try {
        list.Insert(pos, val);
        return true;
    } catch (Exception ex) {
        System.out.println(ex.toString());
        return false;
    }
}

...

TryInsert(mylist, 1, 0);
TryInsert(mylist, 5, 54); //  this is the false entry
TryInsert(mylist, 1, 0);
TryInsert(mylist, 1, 0);

This will give you the output you want, handles any of the inserts kicking out an error, and is more true to the original intent.这将为您提供所需的 output,处理任何引发错误的插入,并且更符合最初的意图。

... but it doesn't feel quite right ……但感觉不太对

Given you are passing in the myList object to every function call, it seems like that object is the thing to be acted upon.鉴于您将myList object 传递给每个 function 调用,似乎要对 object 采取行动。 This would indicate that this is the true desired behaviour of your Insert function.这表明这是您的Insert function 真正需要的行为。

Perhaps you would like to alter your class, either to add this function to it, or modify the Insert to act on its own best judgement when the error occurs (either directly or through inheritance).也许您想更改 class,将这个 function 添加到其中,或者修改Insert以在错误发生时根据自己的最佳判断(直接或通过继承)采取行动。

myList.TryInsert(1, 0);
myList.TryInsert(5, 54); //  this is the false entry
myList.TryInsert(1, 0);
myList.TryInsert(1, 0);

Given I don't have access to your class... I leave it as an exercise to the reader.鉴于我无权访问您的 class... 我将其作为练习留给读者。

refactoring is fun重构很有趣

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM