我尝试让我的代码编译时没有错误,也没有警告作为标准做法。但是,有一个恼人的警告,我知道如何处理.NET而不是Java。假设我有一个这样的代码块:
try {
FileInputStream in = new FileInputStream(filename);
return new Scanner(in).useDelimiter("\\A").next();
} catch (FileNotFoundException ex) {
LOG.log(Level.SEVERE, "Unable to load file: {0}", filename);
return null;
}
我收到警告,表示未使用变量ex
。现在,我没有真正使用ex
,我不想ex
,但我不知道该怎么办。在.NET中,我可以做到:
catch (FileNotFoundException)
没有变量,它将编译并运行,没有错误。
如何在Java中处理这种情况?我知道我可以创建一个局部变量并将其设置为ex
,但这似乎是一个愚蠢而浪费的解决方法来修复不需要的警告。
答案 0 :(得分:11)
记录异常。无论如何,在追逐错误时总是很有用。
答案 1 :(得分:9)
答案 2 :(得分:7)
除了使用它之外,没有干净的方法在Java中“标记ex
使用”。
请注意,根据its documentation,当“[...]文件确实存在但由于某种原因无法访问时,也会抛出FileNotFoundException
,因为例如,当尝试打开只读文件进行写入时。“
因此我建议你做通过打印异常消息来使用异常。
我知道这并没有回答一般性问题,但我几乎无法想到一个例外,当它发生时我至少不会记录某些信息。
答案 3 :(得分:4)
基本上,你是SOL(你必须申报变量并填写警告),因为JAVA在开发方法方面有点躁狂抑郁,或者至少是保姆;这是另一个例子。即使您从未打算使用它,JAVA也会让您声明catch变量。这意味着你有一个未使用的变量只是等待导致问题。虽然有很多关于&#34的评论,你需要使用这个异常变量",这些评论都没有提到问题的重点。问题是"我怎么不得到这个未使用的变量警告",该示例使用FileNotFound异常,但它可能是任何异常。问题不在于FileNotFound异常,而在于未使用的变量警告。
异常类型对此问题并不重要。例如,我有一个管理数据缓冲区的类。它可以抛出异常有几个原因,其中一个原因是数据缓冲区已满。因此,如果我尝试将数据放入完整缓冲区,我的函数可以接收该异常。这是它在这种情况下可以获得的唯一例外。我使用此类的一个函数检测异常并扩展缓冲区。它不关心异常变量,它不记录异常,它处理异常并继续。而不是异常,我可以返回一个标志,指示缓冲区已满,但是失败了异常处理系统(系统中有其他例程,这个异常是一个错误,我处理日志和消息给用户等等。)
因此,我可以将IDE设置为忽略未使用的变量警告。但这不是一个好主意,因为有时候不使用变量表明存在真正的问题(我错过了一段代码或者我忘了结束一个块评论或者什么)。或者,至少,我有一块未使用的代码,可能会在将来增加混乱。我可以压制警告,但这只是一个污点。最重要的是我必须输入一个未使用的变量,记录为什么它没有被使用,以及克服一个解决警告的问题(因此QA不会抱怨)所有因为JAVA想要保护我自己。
<rant>
这是我遇到JAVA的主要问题。 JAVA声称它们是严肃的专业人士用于严肃项目的严肃的编程语言。然而,他们然后假设这些严肃的专业人员总是犯下愚蠢的错误,他们需要保护他们免受这些错误的影响。这几乎就像告诉外科医生他们不能使用手术刀,因为他们可以削减自己。如果您正在为业余爱好者制作玩具编程语言,那么请提供您想要的所有保护措施。但是,如果您声称为专业人士制作语言,那么请为专业人员提供他们完成工作所需的工具。他们是专业人士,给他们专业的工具。像强制定义未使用的变量,不允许操作符重载,没有未签名的原语,以及基本上将用户类视为二等公民这样的事情限制了工具集,并且表明专业工程师不是那么专业的观点。我不介意警告 - 它们有助于开发过程更快。我不喜欢缺乏完整的工具集。这导致了解决问题,克拉奇和一个全新的错误来源。
无论如何,抱歉咆哮
</rant>
答案 4 :(得分:2)
警告是IDE警告,您应该可以将其关闭。
但是,有很多原因可以抛出FileNotFoundException,在这种情况下你会想知道原因。
IntelliJ将ignore
或ignored
识别为故意忽略的异常,或将非空的捕获块视为可接受,具体取决于您的设置。
答案 5 :(得分:1)
如果我使用javac编译该代码,我不会收到警告,所以要么使用不同的编译器,要么使用不同的设置 - 我假设IDE使用了未使用变量的特殊设置。
在eclipse中,我会用注释逐行关闭这些警告,在这种情况下:@SuppressWarnings ("unused")
在之前的行中。
答案 6 :(得分:0)
您应该记录异常。根据{{3}} API,如果文件不存在,可以抛出FileNotFoundException
,是目录而不是常规文件,或者由于某些其他原因无法打开进行读取。“如果遇到这个问题,在日志文件中包含更多详细信息(例如堆栈跟踪)将使其更容易修复。
答案 7 :(得分:0)
几乎每当我认为我没有例外时,一段时间后我就会想到。通常。
如果老实说您无法想到与异常实例有关的任何事情,那么该考虑一下您有没有在程序流程中标识出处理异常的正确位置的可能性。
另一种可能性,也许是您自己编写的异常的可能性更大,是您的异常无法满足您从异常情况中恢复的需要。
希望最不可能的可能性是,您滥用异常系统来执行应使用其他流控制结构(如if或while块)进行的操作。
在我的代数整数计算器项目中,我想知道这一点,在该项目中您可以(或将能够)执行诸如查询8和3√2的最大公约数(GCD)之类的事情。答案当然是√2,但是计算机需要某种算法(例如欧几里得算法)来解决这个问题。
所以我的程序将8除以3√2。这导致抛出NotDivisibleException
。该异常应至少提供一个舍入函数,通过该函数可以将8 /3√2舍入为代数整数。
但是,有时候,我只想知道一个代数整数是否可以被另一个整数整除。例如,
public static boolean isDivisible(AlgebraicInteger a, AlgebraicInteger b) {
try {
a.divides(b);
return true;
} catch (NotDivisibleException nde) {
return false;
} catch (AlgebraicDegreeOverflowException adoe) {
return false;
}
}
您可以想象,这给了我一个未使用的异常警告。这就是为什么我怀疑NotDivisibleException
是否滥用了异常系统的主要原因。
这里有什么选择?我可以在isDivisible
中重写除法函数,以便它在不触发任何异常的情况下为我提供对或错。
因此,与几乎逐字复制除法功能相比,此未使用的异常警告更可取。
对于AlgebraicDegreeOverflowException
,我认为这是运行时异常,应该由调用者而不是isDivisible
捕获。 adoe
子句因此受到攻击。
因此,这给了我一个未使用的异常警告。我认为也许我能做的最好的事情就是将其封装在一个函数中,而不是每次需要进行简单的除数测试时都重复一次。
在该程序的Scala版本中,我可以使用“ _
”表示我实际上不需要异常对象。或者,我什至可以重载模运算符,以便它可以处理AlgebraicInteger
个操作数,或定义一个隐式转换,等等。
但这就是Scala。在Java中,只有三个选项:
最后两个是一样的。
我知道这是八年前的问题。我很想知道您在FileNotFoundException
的情况下决定做什么。
在您的鞋中,我认为在使用getMessage()
函数检索异常消息之后,我至少决定记录该异常消息。您可能无法在此处加上一些其他内容,这可能会建议其他解决方案。