【问题标题】:Issues in scope of variables while using try-catch in Java在 Java 中使用 try-catch 时变量范围的问题
【发布时间】:2015-06-23 18:01:57
【问题描述】:

我有一个类PDF,它实现了一个接口fileReader

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

public class PDF implements fileReader {
    @Override
    public byte[] readFile(File pdfDoc) {
        if (!pdfDoc.exists()) {
            System.out.println("Could not find" + pdfDoc.getName() + " on the specified path");
            return null;
        }
        FileInputStream fin = null;
        try {
            fin = new FileInputStream(pdfDoc);
        } catch (FileNotFoundException e) {
            System.out.println("");
            e.printStackTrace();
        }
        byte fileContent[] = new byte[(int) pdfDoc.length()];
        try {
            fin.read(fileContent);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return fileContent;
    }
}

import java.io.File;
public interface fileReader {
    <T> T readFile(File fileObject);
}

我注意到变量 fin 存在范围问题。

我做的另一个实现是:

public byte[] readFile1(File pdfDoc) {
        if (!pdfDoc.exists()) {
            System.out.println("Could not find" + pdfDoc.getName() + " on the specified path");
            return null;
        }
        FileInputStream fin = null;
        try {
            fin = new FileInputStream(pdfDoc);
            byte fileContent[] = new byte[(int) pdfDoc.length()];
            try {
                fin.read(fileContent);
            } catch (IOException e) {
                System.out.println("");
                e.printStackTrace();
            }
        } catch (FileNotFoundException e) {
            System.out.println("");
            e.printStackTrace();
        }
        return fileContent;
    }

但现在我无法访问fileContent

如何组合try-catches 以免出现范围问题? 有没有更好的设计方法来解决这个问题?我必须编写函数来读取三种不同类型的文件。

【问题讨论】:

  • 您的范围问题究竟是什么?

标签: java scope


【解决方案1】:

从 Java 7 开始,您可以将 try-catch 组合如下:

    FileInputStream fin = null;
    try {
        fin = new FileInputStream(pdfDoc);
        byte fileContent[] = new byte[(int) pdfDoc.length()];
        fin.read(fileContent);
    } catch (IOException | FileNotFoundException e) {
        System.out.println("");
        e.printStackTrace();
    }

在我看来,这使代码更清晰,变量范围更明显。

【讨论】:

  • 哦,太好了,我喜欢这个比我建议的要好得多。我不知道这是可能的。学习新东西:)
  • @DrZoo:这就是 Java 的美妙之处,它让你保持警觉;)
  • 我试过这个,但我得到了Alternatives in a multi-catch statement cannot be related by subclassing Alternative java.io.FileNotFoundException is a subclass of alternative java.io.IOException。我在 Intellij 上使用 Java7
  • 有道理。在这种情况下,您只需要捕获IOException,因为FileNotFoundExceptionIOException 的子类。
【解决方案2】:

您可以嵌套 try catch 语句:

    try {
       FileInputStream fin = new FileInputStream(pdfDoc);
       byte fileContent[] = new byte[(int) pdfDoc.length()];
       try {
          fin.read(fileContent);
          return fileContent;
       } catch (IOException e) {
         e.printStackTrace();
       } finally {
         fin.close();
       }

    } catch (FileNotFoundException e) {
        System.out.println("");
        e.printStackTrace();
    }
    return null;

请注意,我在 finally 子句中添加了 close() 以进行清理。如果出现错误,返回 null 可能不是您想要的,但这是特定于应用程序的。

【讨论】:

  • 我明白了。我曾尝试过,但以错误的方式。谢谢
【解决方案3】:

您可以拥有一个 try 和多个 catch 块。

try {
    //do stuff
}
catch (FileNotFoundException e) {
        System.out.println("");
        e.printStackTrace();
}
catch (IOException e) {
        e.printStackTrace();
}

【讨论】:

    【解决方案4】:

    你可以修改这部分:

            FileInputStream fin = null;
            try {
                fin = new FileInputStream(pdfDoc);
            } catch (FileNotFoundException e) {
                System.out.println("");
                e.printStackTrace();
            }
            byte fileContent[] = new byte[(int) pdfDoc.length()];
            try {
                fin.read(fileContent);
            } catch (IOException e) {
                e.printStackTrace();
            }
    

    {
    ......
           FileInputStream fin = null;
           byte fileContent[]=null;
            try {
                fin = new FileInputStream(pdfDoc);
                fileContent = new byte[(int) pdfDoc.length()];
                fin.read(fileContent);
            } catch (FileNotFoundException e) {
                System.out.println("");
                e.printStackTrace();
            }catch (IOException e) {
                e.printStackTrace();
            }
            return fileContent
        }
    

    【讨论】:

    • 这取决于 Java 版本,如果您使用的是 java 7 或更高版本,您只能使用一个 catch 块,如这个 catch (IOException | FileNotFoundException e)
    【解决方案5】:

    我会这样写:

    public byte[] readFile(File pdfDoc) {
        if (!pdfDoc.exists()) {
            System.out.println("Could not find" + pdfDoc.getName() + " on the specified path");
            return null;
        }
        FileInputStream fin = null;
        byte fileContent[] = new byte[(int) pdfDoc.length()];
    
        try {
            fin = new FileInputStream(pdfDoc);
            fin.read(fileContent);
        } catch (FileNotFoundException e) {
            System.out.println("");
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (null != fin) {
                fin.close();
            }
        }   
        return fileContent;
    }

    【讨论】:

      【解决方案6】:

      从 Java 7 开始,有一个很好的实用方法可以读取文件的全部内容:

      return Files.readAllBytes(pdfFile.toPath());
      

      此方法将为您打开和关闭 FileInputStream,因此您无需自己执行此操作。如果出现问题,它会抛出 IOException。通常,最好让这个异常传播给调用者,但如果你真的想在这种情况下返回 null,你可以这样做:

      try {
          return Files.readAllBytes(pdfFile.toPath());
      } catch (IOException e) {
          e.printStackTrace();
          return null;
      }
      

      这也有一个很好的优势,即在这种情况下返回的值是明确的 - 或者您真的是要在无法找到文件时返回一个填充 0 值的数组,就像您当前的代码一样?

      请注意,由于 NoSuchFileException 是 IOException 的子类,catch 块将同时处理这两种情况。如果你想以不同的方式处理它,你可以为 NoSuchFileException 编写一个单独的 catch 块:

      try {
          return Files.readAllBytes(pdfFile.toPath());
      } catch (NoSuchFileException e) {
          System.err.println("Oh no, the file has disappeared.");
          e.printStackTrace();
          return null;
      } catch (IOException e) {
          System.err.println("The file exists, but could not be read.");
          e.printStackTrace();
          return null;
      }
      

      最后,我可能应该提一下,您的文件读取代码不正确,因为 InputStream.read() 不一定会一次读取整个文件。这就是为什么它返回读取的字节数,以便您可以为文件的其余部分再次调用它。但正如我所说,从 Java 7 开始,您不需要使用如此低级的 API(当然,除非文件太大而无法放入内存)。

      【讨论】:

        猜你喜欢
        • 2011-02-20
        • 2020-02-20
        • 1970-01-01
        • 1970-01-01
        • 2015-12-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多