问题描述
我有以下与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;
}
为了使其与Java 1.6兼容,我需要更改什么?
1楼
真正的答案:
真正的答案是使用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.
}
}
}
但这是因为这是一个非常简单的案例。
如果还有其他需要关闭的资源(例如, 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
}
}
}
您可能需要一些实用程序库函数来帮助解决此问题,否则,这将是很多样板。 在我知道已经发生异常的情况下,我曾经关闭过“无声”的东西。
详细信息: 的第节及其小节 :
一个简单的try-with-resources
:
try ({VariableModifier} R Identifier = Expression ...)
Block
转换为:
{
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();
}
}
}
}
您必须删除addSuppressed
部分,因为Throwable
在JDK6中没有。
扩展的try-with-resources
:
try ResourceSpecification
Block
[Catches]
[Finally]
转换为:
try {
try ResourceSpecification
Block
}
[Catches]
[Finally]
...那
try ResourceSpecification
Block
...被简单的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]
...这就是为什么我们如此喜欢try-with-resources
语句的原因。
2楼
为了使其与Java 1.6兼容,我需要更改什么?
尝试以下代码:
QueryExecution qexec = null;
try {
qexec = QueryExecutionFactory.create(query, input.getModel()));
// Some other code
while (results.hasNext()) {
// do something
}
return something;
} finally {
if (qexec != null){
qexec.close();
}
}
最重要的部分:必须在finally块中手动关闭流。
但是请注意,Oracle Java SE 6甚至现在的Oracle Java SE 7都达到了EoL。 因此,如果您使用的是Oracle的实现并且没有相应的支持合同,那么强烈建议您升级到Java SE 8