使代码与Java 1.6兼容(-source 1.6中不支持try-with-resources)

bet*_*eta 1 java java-6

我有以下与Java 1.7兼容的代码,但是,我需要它与Java 1.6兼容。目前,我收到此代码以下错误:try-with-resources is not supported in -source 1.6

代码如下:

    try (QueryExecution qexec = QueryExecutionFactory.create(query, input.getModel())) {
        // Some other code
        while (results.hasNext()) {
            // do something
        }
        return something;
    }
Run Code Online (Sandbox Code Playgroud)

为了使其与Java 1.6兼容,我需要更改什么?

T.J*_*der 5

真正的答案:

真正的答案是使用Java 7或8。Java 6很老了。Java 7于年前问世。Java 8,将近一年半。

仅在有非常非常好的理由无法阅读时才继续阅读。:-)

TL; DR

特定示例可以很简单:

QueryExecution qexec = QueryExecutionFactory.create(query, input.getModel());
Throwable thrown = null;
try {
    // Some other code
    while (results.hasNext()) {
        // do something
    }
    return something;
}
catch (Throwable t) {
    thrown = t; // Remember we're handling an exception
    throw t;
}
finally {
    try {
        qexec.close();
    }
    catch (Throwable t) {
        if (thrown == null) {
            // Not handling an exception, we can rethrow
            throw t;
        }
        else {
            // Log it or something, you can't allow it to
            // throw because there's *already* an exception
            // being thrown and you'll hide it. This is why
            // Java 7 added Throwable#addSuppressed.
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

但这是因为这是一个非常简单的案例。如果还有其他需要关闭的资源(results例如,?),或者您正在处理代码本身中的某些异常,则情况会更加复杂。

更一般的形式是:

SomeResource r1 = null;
Throwable thrown = null;
try {
    r1 = new SomeResource();

    SomeOtherResource r2 = null;
    try {
        r2 = new SomeOtherResource();
        // use them
        return something;
    }
    catch (Throwable t) {
        thrown = t; // Remember we're handling an exception
        throw t;
    }
    finally {
        try {
            r2.close();
        }
        catch (Throwable t) {
            if (thrown == null) {
                // Not handling an exception, we can rethrow
                throw t;
            }
            else {
                // Log it or something, you can't allow it to
                // throw because there's *already* an exception
                // being thrown and you'll hide it. This is why
                // Java 7 added Throwable#addSuppressed.
            }
        }
    }
}
catch (Throwable t) {
    thrown = t; // Remember we're handling an exception
    throw t;
}
finally {
    try {
        r1.close();
    }
    catch (Throwable t) {
        if (thrown == null) {
            // Not handling an exception, we can rethrow
            throw t;
        }
        else {
            // Log it or something
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

您可能需要一些实用程序库函数来帮助解决此问题,否则,这将是很多样板。在我知道已经发生异常的情况下,我曾经关闭过“无声”的东西。


详细信息:JLS的第14.20.3节及其小节对此进行了介绍

一个简单的try-with-resources

try ({VariableModifier} R Identifier = Expression ...)
    Block
Run Code Online (Sandbox Code Playgroud)

转换为:

{
    final {VariableModifierNoFinal} R Identifier = Expression;
    Throwable #primaryExc = null;

    try ResourceSpecification_tail
        Block
    catch (Throwable #t) {
        #primaryExc = #t;
        throw #t;
    } finally {
        if (Identifier != null) {
            if (#primaryExc != null) {
                try {
                    Identifier.close();
                } catch (Throwable #suppressedExc) {
                    #primaryExc.addSuppressed(#suppressedExc);
                }
            } else {
                Identifier.close();
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

您必须删除该addSuppressed部分,因为ThrowableJDK6中没有该部分。

扩展try-with-resources

try ResourceSpecification
    Block
[Catches]
[Finally]
Run Code Online (Sandbox Code Playgroud)

转换为:

try {
    try ResourceSpecification
        Block
}
[Catches]
[Finally]
Run Code Online (Sandbox Code Playgroud)

...那

try ResourceSpecification
    Block
Run Code Online (Sandbox Code Playgroud)

...被简单的大事情所代替try-with-resources,所以整个事情变成了:

try {
    {
        final {VariableModifierNoFinal} R Identifier = Expression;
        Throwable #primaryExc = null;

        try ResourceSpecification_tail
            Block
        catch (Throwable #t) {
            #primaryExc = #t;
            throw #t;
        } finally {
            if (Identifier != null) {
                if (#primaryExc != null) {
                    try {
                        Identifier.close();
                    } catch (Throwable #suppressedExc) {
                        #primaryExc.addSuppressed(#suppressedExc);
                    }
                } else {
                    Identifier.close();
                }
            }
        }
    }
}
[Catches]
[Finally]
Run Code Online (Sandbox Code Playgroud)

...这就是为什么我们try-with-resources如此喜欢这种说法的原因。