就像我有这两个场景,我们必须处理FileNotFoundException
情况1:
try {
FileInputStream fis = new FileInputStream("test1.txt");
} catch (FileNotFoundException e) {
e.printStackTrace();
}
情况2:
try {
FileInputStream fis = new FileInputStream("test1.txt");
} catch (Exception e) {
e.printStackTrace();
}
在两种情况下,打印的Stack Trace都是相同的。我想知道两种实现之间的区别以及应该首选的内容吗?
答案 0 :(得分:5)
从docs它给出了原因:
"子类继承所有成员(字段,方法和嵌套 来自其超类的类)。构造者不是成员,所以他们 不是由子类继承,而是超类的构造函数 可以从子类调用。"
异常类是所有其他异常类的父级。因此,如果您知道要获得FileNotFoundException
,那么最好使用该异常。使Exception
成为通用调用。
这有助于您理解:
因为您可以看到Exception类处于更高的层次结构中,因此它意味着它将捕获除FileIOExcetion之外的任何异常。但是,如果要确保尝试打开由指定路径名表示的文件失败,则必须使用FileIOExcetion。
所以这是理想的方法:
try {
// Lets say you want to open a file from its file name.
} catch (FileNotFoundException e) {
// here you can indicate that the user specified a file which doesn't exist.
// May be you can try to reopen file selection dialog box.
} catch (IOException e) {
// Here you can indicate that the file cannot be opened.
}
同时对应:
try {
// Lets say you want to open a file from its file name.
} catch (Exception e) {
// indicate that something was wrong
// display the exception's "reason" string.
}
答案 1 :(得分:1)
在第2种情况下,将对所有被捕获的Exception
运行catch块,而不管它们是什么异常。这允许以相同的方式处理所有异常,例如为所有类型的异常显示相同的消息。
在案例1中,catch
块仅运行FileNotFoundException
。捕获不同catch
块中的特定异常允许以不同方式处理不同的异常,例如向用户显示不同的消息。
答案 2 :(得分:1)
当发生异常时,JVM会抛出Exception的实例,并且该实例将传递给相应的catch块,因此在 <input type="file" name="archivo" accept=".doc, .pfd, .docx"/>
中e只是引用变量,但它指向的实例是抛出异常的。
在 $archivo = $_FILES["archivo"]["tmp_name"];
$tamanio = $_FILES["archivo"]["size"];
$tama = $_FILES["archivo"]["size"];
$tipo = $_FILES["archivo"]["type"];
$nombre = $_FILES["archivo"]["name"];
$titulo = $_POST["titulo"];
if ( $archivo != "none" )
{
$fp = fopen($archivo, "rb");
$contenido = fread($fp, $tamanio);
$contenido = addslashes($contenido);
fclose($fp);
$qry = "INSERT INTO archivos VALUES
(0,'$nombre','$Nombre','$tama','$contenido','$tipo')";
mysql_query($qry) or die('Consulta fallida: ' . mysql_error());
if(mysql_affected_rows($link) > 0)
print "Se ha guardado el archivo en la base de datos.";
else
print "NO se ha podido guardar el archivo en la base de datos.";
}
else
print "No se ha podido subir el archivo al servidor";
的情况下,e也是一个引用变量,它指向的实例是抛出Exception,因此在两种情况下,不同的引用varibales(即e)都指向异常的实例(被抛出)。
这是我更喜欢的:
catch(Exception e)
答案 3 :(得分:0)
这是你要拦截的问题。使用Exception
,您将捕获任何异常,但使用FileNotFoundException
,您将只捕获该错误情况,允许调用者捕获并应用任何处理。
答案 4 :(得分:0)
不要使用其中任何一种。
不要抓住Exception
。为什么?因为它还捕获所有未经检查的异常(即RuntimeException
和派生词)。那些应该被重新抛出。
Don't use the old file API。为什么?因为它的异常是不可靠的(例如,如果您尝试打开一个您没有读取权限的文件,则可以抛出FileNotFoundException
。)
使用:
final Path path = Paths.get("test1.txt");
try (
final InputStream in = Files.newInputStream(path);
) {
// do something with "in"
} catch (FileSystemException e) {
// fs level error: no permissions, is a directory etc
} catch (IOException e) {
// I/O error
}
你需要在FileSystemException
之前捕获IOException
,因为前者是后者的子类。您可以使用其他可能的例外:AccessDeniedException
,FileSystemLoopException
,NoSuchFileException
等。
答案 5 :(得分:0)
异常类是FileNotFoundException的父级。
如果您已在catch语句中提供了Exception,则每个Exception都将在catch块中处理。但是如果catch块中存在FileNotFoundException,则只会处理由于缺少所述源上的File或者无法读取该文件的权限而导致的异常,或者会导致破坏Java努力读取该文件的任何此类问题。所有其他异常都会逃逸并向上移动。
在您提供的代码段中,可以同时使用它们。但我会建议FileNotFoundException,因为它指向代码中的确切问题。
有关详情,请参阅Go Here
答案 6 :(得分:0)
当你这样写:
try {
FileInputStream fis = new FileInputStream("test1.txt");
} catch (FileNotFoundException e) {
e.printStackTrace();
}
只有当异常(在try块中抛出)的类型为FileNotFoundException
(或子类型)时,才会执行catch块内的代码。
当你写这篇文章时,另一方面:
try {
FileInputStream fis = new FileInputStream("test1.txt");
} catch (Exception e) {
e.printStackTrace();
}
对任何异常执行catch块(因为Exception
是任何异常的根类型。)
如果您的文件(test1.txt)不存在,则抛出FileNotFoundException,并且两个代码片段都能够捕获它。 尝试将其更改为:
try {
FileInputStream fis = new FileInputStream("test1.txt");
} catch (NullPointerException e) {
e.printStackTrace();
}
您将看到不再执行catch块。