- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
以下代码使用 try
-with-resources Java 8 中引入的构造。occasionallyThrow() 方法声明为抛出 OccasionalException,Resource 的 close() 方法抛出 CloseException。 Eclipse(版本:Neon Release (4.6.0),Build id:20160613-1800)在标有//dead code的行添加了一个警告,提示该分支是dead code。隐式地,Eclipse 确认标有//alive code 的行不是死代码。
Object tryWithResources() throws OccasionalException {
Object value = null;
try (Resource resource = new Resource()) {
occasionallyThrow();
value = new Object();
}
catch (CloseException e) {
if (value == null) {
// alive code
}
else {
// dead code
}
}
return value;
}
我对此感到困惑。如果 occasionallyThrow() 抛出它的 OccasionalException,那么 try
-with-resources 应该将其捕获为主要异常,然后尝试关闭资源.如果关闭资源抛出一个CloseException,那么它将被抑制在OccasionalException下,所以不会有CloseException被捕获。因此,唯一应该捕获 CloseException 的时间是 try 中的 block 成功完成,这意味着 value 不为空。所以看起来“死代码”实际上是活的,“活代码”实际上是死的。我不确定这里的编译器实际上应该识别什么,但至少,这里的“死代码”似乎不应该被称为死代码。
让事情变得更复杂的是,没有使用 try-with-resources 形式的翻译形式根本不会被标记为任何死代码警告。 (基于 14.20.3.2. Extended try-with-resources ,我非常有信心我的翻译是正确的,但如果这里有错误,我不会感到完全惊讶……)
Object expandedTry() throws OccasionalException {
Object value = null;
try {
Resource resource = new Resource();
Throwable $primary = null;
try {
occasionallyThrow();
value = new Object();
}
catch (Throwable t) {
$primary = t;
throw t;
}
finally {
if (resource != null) {
if ($primary != null) {
try {
resource.close();
}
catch (Throwable $suppressed) {
$primary.addSuppressed($suppressed);
}
}
else {
resource.close();
}
}
}
}
catch (CloseException e) {
if (value == null) {
// alive (not dead!)
}
else {
// alive
}
}
return value;
}
我是否遗漏了一些东西,这些东西会使 if-else 中的任一分支在其中一个分支中死亡,但在另一个分支中却没有?
这是包含辅助异常类型、Resource 类和顶级类定义的完整代码。
public class TestTryWithResources {
/** Exception thrown by Resource's close() method */
@SuppressWarnings("serial")
static class CloseException extends Exception {}
/** AutoCloseable declared to throw a CloseException */
static class Resource implements AutoCloseable {
@Override
public void close() throws CloseException {}
}
/** An occasionally thrown exception */
@SuppressWarnings("serial")
static class OccasionalException extends Exception {}
/** Method declared to throw an occasional exception */
void occasionallyThrow() throws OccasionalException {}
/*
* Method using try-with-resources. Eclipse warns that the
* portion marked with "// dead code" is Dead code.
*/
Object tryWithResources() throws OccasionalException {
Object value = null;
try (Resource resource = new Resource()) {
occasionallyThrow();
value = new Object();
}
catch (CloseException e) {
if (value == null) {
// alive code
}
else {
// dead code
}
}
return value;
}
/*
* Method not using try-with-resources. This is the translation
* of the try-with-resources in tryWithResources, according to
* [14.20.3 try-with-resources][1]. Eclipse does not warn about
* any of the code being Dead code.
*
* [1]: https://docs.oracle.com/javase/specs/jls/se7/html/jls-14.html#jls-14.20.3
*/
Object expandedTry() throws OccasionalException {
Object value = null;
try {
Resource resource = new Resource();
Throwable $primary = null;
try {
occasionallyThrow();
value = new Object();
}
catch (Throwable t) {
$primary = t;
throw t;
}
finally {
if (resource != null) {
if ($primary != null) {
try {
resource.close();
}
catch (Throwable $suppressed) {
$primary.addSuppressed($suppressed);
}
}
else {
resource.close();
}
}
}
}
catch (CloseException e) {
if (value == null) {
// alive
}
else {
// alive
}
}
return value;
}
}
Amin J's answer建议在设置 value 后使用资源来更改 Eclipse 的代码分析。但这不起作用。使用资源后,例如通过打印它,死代码警告仍然存在于 Luna 和 Neon 中:
最佳答案
出于某种原因,静态代码分析器认为根据 this,资源将在 try 声明后立即关闭。 tutorial 声明后资源关闭。
try-with-resources 语句确保每个资源都在语句结束时关闭。
因此,例如,如果您更改代码以在值为 is 之后使用资源(下面的代码),它不会警告您有关死代码的信息(但是在 Eclipse Luna 上测试过)。
Object tryWithResources() throws OccasionalException {
Object value = null;
try (Resource resource = new Resource()) {
occasionallyThrow();
value = new Object();
resource.someMethod(); // using the resource, so eclipse thinks it's not closed yet (correctly)
}
catch (CloseException e) {
if (value == null) {
// alive code
}
else {
// dead code
}
}
return value;
}
更新
这是我在设置值后使用资源(在本例中为 reader)测试的实际代码。
Object val = null;
try (BufferedReader reader = new BufferedReader(new FileReader("C:\\file.txt"))) {
val = new Object();
System.out.println("got here");
reader.readLine();
}
catch(IOException e){
System.out.println("io ex");
if ( val == null){
}
else{
}
}
关于java - try-with-resources 中的死代码警告,但不是翻译的 try-catch-finally,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39598715/
我刚刚遇到了一个非常奇怪的行为。这是代码: // So far everything's fine val x: Try[Try[Unit]] = Try(Try{}) x: scala.util.T
“输出”是一个序列化的 OpenStruct。 定义标题 try(:output).try(:data).try(:title) 结束 什么会更好? :) 最佳答案 或者只是这样: def title
我有以下元组 - (t1,t2) :(Try,Try) 我想检查两者是否成功或其中之一是否失败,但避免代码重复。像这样的东西: (t1,t2) match { case (Success(v1),Su
是否必须放置内部 try-with-resources 或其中一个 try-with-resources 中的所有内容都会自动关闭? try (BasicDataSource ds = Bas
有一点特殊,尝试创建一段 try catch 代码来处理 GoogleTokenResponse,但编译器在 try 时抛出异常错误。有什么想法吗? 错误信息: | Loading Grails 2.
它几乎可以在所有语言中找到,而且我大部分时间都在使用它。 我不知道它是内部的,不知道它是如何真正起作用的。 它如何在任何语言的运行时在 native 级别工作? 例如:如果在 try 内部发生 sta
为什么在 readFile2() 中我需要捕获 FileNotFoundException 以及稍后由 close( ) 方法,并且在 try-with-resources(inside readfi
我正在使用 Apache POI 尝试读取 Word 文件,但即使您使用过 Apache POI,这仍然应该是可以回答的。在 HWPF.extractor 包中有两个对象:WordExtractor
如果try-catch的catch block 中抛出异常,那么finally block 会被调用吗? try { //some thing which throws error } cat
这个问题已经有答案了: What's the purpose of try-with-resources statements? (7 个回答) 已关闭 3 年前。 我一直在查看代码,并且已经看到了对
这个问题已经有答案了: What's the purpose of try-with-resources statements? (7 个回答) 已关闭 3 年前。 我一直在查看代码,并且已经看到了对
我正在使用 Try::Tiny尝试捕捉。 代码如下: use Try::Tiny; try { print "In try"; wrongsubroutine(); # undefi
我想知道这样的代码是否会在抛出异常后总是中断而不继续运行,因此代码不会继续执行第二个 temp.dodaj(b)。 Avto *a = new Avto("lambo",4); Avt
我知道在try子句中必须有一个与资源关联的变量声明。 但是除了被分配一个通常的资源实例化之外,它是否可以被分配一个已经存在的资源,例如: public String getAsString(HttpS
我有一个写的方法。此方法仅扫描用户输入的整数输入。如果用户输入一个字符值,它将抛出一个输入不匹配异常,这是在我的 Try-Catch 语句中处理的。问题是,如果用户输入任何不是数字的东西,然后抛出异常
我注意到这不会编译: PrintWriter printWriter = new PrintWriter("test.txt"); printWriter.append('a'); printWrit
我经常看到人们写这样的代码: try: some_function() except: print 'something' 当我认为这样做更干净时: try: some_functio
该应用程序将在第二个显示器上正常显示内容。问题是当我旋转 iPad 时内容不会在 iPad 上旋转。 看过: http://developer.apple.com/library/ios/#qa/qa
我正在学习 java,我发现我不喜欢的一件事通常是当我有这样的代码时: import java.util.*; import java.io.*; public class GraphProblem
我使用 C++ 有一段时间了,对普通的 try/catch 很熟悉。但是,我现在发现自己在 Windows 上,在 VisualStudio 中编码以进行 COM 开发。代码的几个部分使用了如下内容:
我是一名优秀的程序员,十分优秀!