【问题标题】:Properly places try and catches正确放置尝试和捕获
【发布时间】:2015-07-21 00:45:16
【问题描述】:

我对正确使用 try 和 catch 语句有疑问。

以前我在 main 方法中拥有所有这些代码并且它可以工作,但是当我想将它放入分离线程时出现问题。

以前我使用' throws IOException,但是在实现Runnable 的类中我不能只使用throws IOException,因为有错误。 我想得到一些建议,如何让这段代码在线程中再次工作。

我将不胜感激与改进我的代码有关的所有建议。

public void run() { 
        File file= new File("Towar.txt");
      Scanner sc;
      BufferedReader br;
    try {
        sc = new Scanner(file);
        br= new BufferedReader(new FileReader(file));
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    }


        String line;
        int count=0;
        while (sc.hasNextLine()) {

            line = br.readLine();
            if (line==null)break;

            int space = line.indexOf(" ");

            int id_towaru = Integer.parseInt(line.substring(0, space));
            double waga = Double.parseDouble(line.substring(space));
            Towar tow= new Towar(id_towaru,waga);
            count++;
            if (count%200==0)System.out.println("Created: "+ count + " objects");

        }   

    }

}

【问题讨论】:

  • try/catch包裹一下,有什么问题?
  • 请向我们展示您尝试使用 try/catch。否则我们怎么知道你可能做错了什么?
  • 当我用try-catch自动换行时,非初始化变量有问题
  • @jawjaw 不在这里,请编辑问题。

标签: java multithreading ioexception


【解决方案1】:
  1. 在 try/catch 之前将 Scanner 变量 sc 初始化为 null。错误消失了。
  2. 不要尝试同时使用 Scanner BufferedReader 读取文件,而应使用其中一个。

Scanner sc = null;
try {
    sc = new Scanner(file);
} catch (FileNotFoundException e) {
    e.printStackTrace();
    // exit program here?
}

【讨论】:

  • 谢谢,但我使用了“while (sc.hasNextLine())”,因为如果我使用 br.readline()!= null,我只会从文件中读取一半的行。
  • @jawjaw:那你做错了。你有一个错误,解决方案是找到并修复这个错误,而不是像你正在做的那样使用一些易碎的东西。
  • @jawjaw 如果您使用sc.hasNextX(),获取X 的正确方法是调用sc.nextX(),无论X 是什么。由于您使用的是sc.hasNextLine(),因此您应该使用sc.nextLine() 来阅读下一行。
【解决方案2】:

虽然@HovercraftFullOfEels 已经给了你答案,但我想解释一下为什么你会收到这个错误。

Java 要求在使用变量之前对其进行赋值。见Chapter 16. Definite Assignment - 16.2.15. try Statements

V 在catch 块之前明确分配当且仅当V 在try 块之前明确分配。

...早在same chapter:

每个局部变量(第 14.4 节)和每个空白最终字段(第 4.12.4 节、第 8.3.1.2 节)在对其值进行任何访问时都必须具有明确分配的值。

【讨论】:

    【解决方案3】:

    您遇到的问题是由于 runnable 是被异步调用的,所以没有什么“等待”它,它也不能有返回值。

    取决于您的应用程序的其余部分,以及它是如何被调用的,有多少并行的东西被调用等等,您有两个主要选择:

    1.) 如果启动运行此 runnable 的线程的东西并不真正关心结果,您可以在 run() 方法中执行 try catch。然后由 catch 块来采取适当的行动:

    public void run() {
        try {
            // do some stuff
        } catch (Exception e) {
            // write some kind of error log
        }
    }
    

    2.) 做同样事情的另一种方法是使用“Callable”而不是“Runnable”。 Callable 可以像 Runnable 一样被调度,但是它可以抛出异常,并且它可以有一个返回值。

    public MyCallable implements Callable<String> {
    
        public String call() throws Exception {
            // do stuff
        }
    
    }
    

    现在,如果您使用这种方法,您将需要某种执行器,并提交可调用的执行。这将返回一个

    Future<String>
    

    您可以在其上调用各种会抛出异常的 get() 方法(如果您的代码抛出异常或您遇到超时),否则将返回实际的返回值。

    一个简单的例子:

    http://www.journaldev.com/1090/java-callable-future-example

    【讨论】:

      【解决方案4】:

      这就是您的新方法应有的样子。以下代码将在正确的位置捕获异常,并且还将关闭所有流以防止资源泄漏。

      public void run() {
          try {
              File file = new File("Towar.txt");
              Scanner sc = new Scanner(file);
              BufferedReader br = new BufferedReader(new FileReader(file));
              String line;
              int count = 0;
              while (sc.hasNextLine()) {
      
                  line = br.readLine();
                  if (line == null)
                      break;
      
                  int space = line.indexOf(" ");
      
                  int id_towaru = Integer.parseInt(line.substring(0, space));
                  double waga = Double.parseDouble(line.substring(space));
                  Towar tow= new Towar(id_towaru,waga);
                  count++;
                  if (count % 200 == 0)
                      System.out.println("Created: " + count + " objects");
      
              }
              sc.close();
              br.close();
          } catch (IOException ioe) {
              ioe.printStackTrace();
          }
      }
      

      【讨论】:

        【解决方案5】:

        你想使用 try catch 的地方可能会像这行一样失败:

        try{
        int id_towaru = Integer.parseInt(line.substring(0, space));
        }
        catch(Exception e){
        //something you want this part to do, eks:
        System.out.println("did not find Integer");
        }
        

        【讨论】:

          【解决方案6】:
          catch (FileNotFoundException e) {
              e.printStackTrace();
          }
          

          发生异常后,您的代码会愉快地继续解析输入文件。这没有意义,因为文件不存在,所以应该跳过解析。有两种方法可以做到这一点:

          1. e.printStackTrace(); 之后添加return。这将跳过方法主体的其余部分
          2. 通过将catch 块移动到代码中的while 语句下方,将整个解析代码封装在try/catch 语句中。

          File file= new File("Towar.txt");
          Scanner sc;
          BufferedReader br;
          try {
              sc = new Scanner(file);
              br= new BufferedReader(new FileReader(file));
          
              String line;
              int count=0;
              while (sc.hasNextLine())
              {
                  line = br.readLine();
                  if (line==null)break;
          
                  int space = line.indexOf(" ");
          
                  int id_towaru = Integer.parseInt(line.substring(0, space));
                  double waga = Double.parseDouble(line.substring(space));
                  Towar tow= new Towar(id_towaru,waga);
                  count++;
                  if (count%200==0)System.out.println("Created: "+ count + " objects");
              }
          }
          catch (FileNotFoundException e)
          {
              e.printStackTrace();
          }
          

          虽然第一个解决方案可能更好看(因为它避免了过多的缩进),但第二个解决方案可能更容易理解。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2017-09-12
            • 1970-01-01
            • 1970-01-01
            • 2018-01-10
            • 1970-01-01
            • 1970-01-01
            • 2019-08-25
            相关资源
            最近更新 更多